diff --git a/Dockerfile b/Dockerfile
index dc06a35..3523a3b 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM maven:3.9-eclipse-temurin-17 as compilador
+FROM maven:3.9-eclipse-temurin-25 as compilador
RUN echo "Se crea carpeta de servidor" && \
mkdir app
@@ -10,7 +10,7 @@ RUN echo "Se compila la aplicación" && \
mvn clean package -DskipTests && \
cp -f server.app/target/*.jar ./servidor.jar
-FROM eclipse-temurin:17-jre
+FROM eclipse-temurin:25-jre
LABEL version=1.0.0
LABEL description="Jonnattan Griffiths"
diff --git a/README.md b/README.md
index 64235cf..0db252e 100644
--- a/README.md
+++ b/README.md
@@ -1,24 +1,183 @@
-# Emulador de algunas cosas interesantes
-
-Emula el comportamiento de algunas aplicaciones que me siven para el desarrollo mobile
-Ideal para hacer pruebas en desarrollo, se utilizara este servidor con mi pagina de prueba
-
-##
-Utiliza Spring boot durante el desarrollo
-
-##
-Está programado en JAVA con Spring boot y una conexión a base de datos MySQL
-
+# Emulator Server API
[](https://sonarcloud.io/summary/new_code?id=jonnattangc_java.server)
-[](https://sonarcloud.io/summary/new_code?id=jonnattangc_java.server)
-[](https://sonarcloud.io/summary/new_code?id=jonnattangc_java.server)
[](https://sonarcloud.io/summary/new_code?id=jonnattangc_java.server)
-[](https://sonarcloud.io/summary/new_code?id=jonnattangc_java.server)
-[](https://sonarcloud.io/summary/new_code?id=jonnattangc_java.server)
-[](https://sonarcloud.io/summary/new_code?id=jonnattangc_java.server)
-[](https://sonarcloud.io/summary/new_code?id=jonnattangc_java.server)
+[](https://sonarcloud.io/summary/new_code?id=jonnattangc_java.server)
[](https://sonarcloud.io/summary/new_code?id=jonnattangc_java.server)
+[](https://sonarcloud.io/summary/new_code?id=jonnattangc_java.server)
+[](https://sonarcloud.io/summary/new_code?id=jonnattangc_java.server)
[](https://sonarcloud.io/summary/new_code?id=jonnattangc_java.server)
[](https://sonarcloud.io/summary/new_code?id=jonnattangc_java.server)
+[](https://sonarcloud.io/summary/new_code?id=jonnattangc_java.server)
+[](https://sonarcloud.io/summary/new_code?id=jonnattangc_java.server)
+[](https://sonarcloud.io/summary/new_code?id=jonnattangc_java.server)
+
+---
+
+## Resumen
+
+Emulador de APIs de terceros construido para apoyar el desarrollo mobile y pruebas de integración. Expone endpoints REST que replican el comportamiento de servicios de pago, tokenización, autenticación y gestión de tarjetas, y persiste transacciones, tarjetas, usuarios y configuraciones en MySQL.
+
+## Tecnologías
+
+| Componente | Versión |
+|---------------------|----------|
+| Java | 21 |
+| Spring Boot | 4.0.5 |
+| MySQL Connector | 8.0.33 |
+| Lombok | 1.18.38 |
+| BouncyCastle | 1.70 |
+| Apache HttpClient | 4.5.14 |
+| Log4j2 | 2.21.0 |
+| JUnit | 4.13.1 |
+| Maven | 3.9 |
+
+## Arquitectura
+
+Proyecto Maven multi-módulo:
+
+| Módulo | Responsabilidad |
+|-------------------|----------------------------------------------------------------------------------|
+| `server.app` | Aplicación Spring Boot. Controllers REST y punto de entrada (`Application.java`). |
+| `server.services` | Lógica de negocio, configuración, seguridad, criptografía y utilidades. |
+| `server.dao` | Repositorios Spring Data JPA. |
+| `server.domain` | Entidades JPA (`Card`, `Transaction`, `User`, `Device`, `Configuration`) y enums. |
+| `server.json` | DTOs de request/response y serialización Jackson. |
+
+```
+java.server/
+├── server.app/ # Controllers y bootstrap Spring Boot
+├── server.services/ # Servicios, configuración y utilidades
+├── server.dao/ # Repositorios JPA
+├── server.domain/ # Entidades y enums
+├── server.json/ # DTOs
+├── Dockerfile
+├── docker-compose.yml
+└── pom.xml # POM raíz
+```
+
+## Endpoints
+
+> Base path: `${CONTEXT}` (por defecto `/emulator`). Todos los ejemplos omiten el context path.
+
+### Configuración dinámica — `/config`
+
+| Método | Path | Request | Response | Descripción |
+|--------|-------------------|----------------------------------|-----------------------------------|-----------------------------------------------|
+| POST | `/config/create` | `AppConfigurationRequestDTO` | `String` | Crea configuración para un endpoint. |
+| POST | `/config/update` | `AppConfigurationRequestDTO` | `String` | Actualiza configuración existente. |
+| POST | `/config/save` | `AppConfigurationRequestDTO` | `String` | Persiste la configuración. |
+| GET | `/config/list` | — | `AppListConfigurationDTOResponse` | Lista todas las configuraciones. |
+
+### Pagos y Tokens (TecApi) — `CetipaController`
+
+| Método | Path | Request | Response | Descripción |
+|--------|---------------------------------------------------|--------------------------------------------|----------------|-----------------------------------------------------------|
+| POST | `/pay/ptm/v1/authorizations` | `EdrPayAuthorizeRequestDTO` | `IEmulator` | Autoriza una transacción de pago. |
+| POST | `/pay/ptm/v1/voids` | `EdrPaymentReverseRequestDTO` | `IEmulator` | Reversa o anula una transacción autorizada. |
+| POST | `/tsp/ttm/v1/enrollments` | `EdrTokenEnrollmentRequestDTO` | `IEmulator` | Enrola un dispositivo o tarjeta. |
+| POST | `/tsp/ttm/v1/par/search` | `EdrTokenGetDigitalPanRequestDTO` | `IEmulator` | Búsqueda de tarjeta digital (PAR). |
+| GET | `/tsp/ttm/v1/tokens/{token}` | — | `IEmulator` | Obtiene el detalle del token. |
+| POST | `/tsp/ttm/v1/tokens/{token}/acquired` | — | `String` | Notifica que el token fue adquirido. |
+| POST | `/tsp/ttm/v1/tokens/{token}/cryptograms` | `EdrPaymentCreateCryptogramRequestDTO` | `IEmulator` | Genera criptograma para el token. |
+| POST | `/pay/prm/v1/requestors/{requestor}/logon` | `EdrPaymentLogonRequestDTO` | `IEmulator` | Logon PRM (Payment Requestor). Retorna `access_token` en header. |
+| POST | `/tsp/trm/v1/requestors/{requestor}/logon` | `EdrTokenLogonRequestDTO` | `IEmulator` | Logon TRM (Token Requestor). Retorna `access_token` en header. |
+
+### Commerce — `/commerceapps`
+
+| Método | Path | Request | Response | Descripción |
+|--------|---------------------------|---------------------------|----------------------------|------------------------------------------|
+| POST | `/commerceapps/sendMail` | Body crudo | `CommerceMailResponseDTO` | Simula envío de email desde Commerce. |
+| POST | `/commerceapps/getToken` | `MultiValueMap` (headers) | `CommerceTokenResponseDTO` | Emite token de acceso emulado. |
+
+### CXP (proxy ChileExpress) — `/cxp`
+
+| Método | Path | Request | Response | Descripción |
+|--------|-------------|-------------------------|---------------------|----------------------------------------------------------|
+| POST | `/cxp/**` | `HttpServletRequest` | `ICxpResponse` | Reenvía POST al backend CXP configurado dinámicamente. |
+| GET | `/cxp/**` | `HttpServletRequest` | `String` | Reenvía GET al backend CXP configurado dinámicamente. |
+
+### Logon externos — `/edr`
+
+| Método | Path | Request | Response | Descripción |
+|--------|---------------------------|---------------------------|------------|---------------------------------|
+| POST | `/edr/login/tickettest` | `MultiValueMap` (headers) | `String` | Logon de prueba (EDR). |
+| POST | `/edr/login/ticket` | `MultiValueMap` (headers) | `String` | Logon EDR. |
+| POST | `/edr/login/beanuj` | `MultiValueMap` (headers) | `String` | Logon JUNAEB. |
+
+### EDR-EGD Foods
+
+| Método | Path | Request | Response | Descripción |
+|--------|-----------------------------|-----------------------|---------------|------------------------------------------|
+| ANY | `/api/v1/foods/cards/**` | `HttpServletRequest` | `IEmulator` | Búsqueda y procesamiento de tarjetas. |
+
+### Página personal — `/page`
+
+| Método | Path | Request | Response | Descripción |
+|--------|----------------------|--------------------------------------|---------------|--------------------------------------|
+| POST | `/page/users/save` | `MultiValueMap` (form-urlencoded) | `IEmulator` | Registra un usuario nuevo (CORS). |
+| GET | `/page/users` | — | `IEmulator` | Lista los usuarios (CORS). |
+
+## Configuración
+
+La aplicación selecciona su perfil activo mediante la variable `ENV` (`local`, `dev`, `prod`).
+
+### Variables de entorno
+
+| Variable | Descripción | Default |
+|--------------|-------------------------------------------------|---------------|
+| `ENV` | Perfil Spring activo. | `dev` |
+| `PORT` | Puerto HTTP del servidor. | `8089` |
+| `CONTEXT` | Context path de la aplicación. | `/emulator` |
+| `BD_ADDR` | Host MySQL. | — |
+| `BD_PORT` | Puerto MySQL. | `3306` |
+| `BD_NAME` | Nombre del esquema. | — |
+| `BD_USER` | Usuario MySQL. | — |
+| `BD_PASS` | Password MySQL. | — |
+| `LOG_LEVEL` | Nivel de logging (`DEBUG`, `INFO`, ...). | `INFO` |
+| `AES_KEY` | Clave AES para cifrado (32+ caracteres). | — |
+
+### Persistencia
+
+- JDBC URL: `jdbc:mysql://${BD_ADDR}:${BD_PORT}/${BD_NAME}?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true&autoReconnect=true`
+- Pool: HikariCP (`max-pool-size=10`, `connection-timeout=30s`).
+- DDL: `hibernate.ddl-auto=update` en ambientes de desarrollo.
+- Perfil `local` usa H2 en memoria.
+
+## Ejecución
+
+### Maven
+
+```bash
+export ENV=local
+export PORT=8089
+export CONTEXT=/emulator
+export LOG_LEVEL=DEBUG
+export AES_KEY=''
+export BD_ADDR=localhost
+export BD_PORT=3306
+export BD_NAME=emulator
+export BD_USER=emulator
+export BD_PASS=''
+
+mvn clean package
+java -Xmx1024m -Xms512m -jar server.app/target/server.app-1.2.0-SNAPSHOT.jar
+```
+
+### Docker
+
+```bash
+docker build -t java-server:v1 .
+docker-compose up -d
+```
+
+`docker-compose.yml` publica el puerto `8089` y lee las variables desde `../envs/java_server.env`. El `Dockerfile` usa build multi-stage con Maven 3.9 y Eclipse Temurin 25 como runtime.
+
+## Seguridad
+
+Consulta [SECURITY.md](./SECURITY.md) para la política de reporte de vulnerabilidades.
+
+## Licencia
+
+Ver [LICENSE](./LICENSE).
diff --git a/docker-compose.yml b/docker-compose.yml
index 6f08d09..7580be6 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -6,10 +6,10 @@ services:
restart: always
deploy:
replicas: 1
- env_file:
- - ../envs/java_server.env
+ env_file:
+ - ../envs/java_server.env
networks:
- - db-net
+ - db-net
ports:
- 8089:8089
networks:
diff --git a/pom.xml b/pom.xml
index 9fdf662..f57c9d9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,13 +21,13 @@
21
1.2.0-SNAPSHOT
4.0.5
- 4.13.1
1.1.4
2.6.1
1.1.4
1.0.0
1.18.38
4.2.1
+ 0.8.12
@@ -43,12 +43,6 @@
${spring.boot.version}
test
-
- junit
- junit
- ${junit.version}
- test
-
org.springframework.boot
spring-boot-dependencies
@@ -154,6 +148,26 @@
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco.version}
+
+
+ prepare-agent
+
+ prepare-agent
+
+
+
+ report
+ verify
+
+ report
+
+
+
+
\ No newline at end of file
diff --git a/server.app/pom.xml b/server.app/pom.xml
index b8de5ed..da98c18 100644
--- a/server.app/pom.xml
+++ b/server.app/pom.xml
@@ -18,8 +18,8 @@
- junit
- junit
+ org.junit.jupiter
+ junit-jupiter
test
diff --git a/server.app/src/main/java/cl/jonnattan/emulator/controllers/AppCommeController.java b/server.app/src/main/java/cl/jonnattan/emulator/controllers/AppCommeController.java
index 6e8a414..ab7fc57 100644
--- a/server.app/src/main/java/cl/jonnattan/emulator/controllers/AppCommeController.java
+++ b/server.app/src/main/java/cl/jonnattan/emulator/controllers/AppCommeController.java
@@ -21,11 +21,11 @@
/**
* Controlles respuesta a la APPs Cmc
- *
+ *
* @author Jonnattan Griffiths
* @since Programa EMULADOR
* @version 1.0 del 30-09-2020
- *
+ *
*/
@RestController
@RequestMapping("/commerceapps")
@@ -43,8 +43,9 @@ public ResponseEntity sendMail(HttpServletRequest reque
int dato = -1;
ServletInputStream sis = request.getInputStream();
ByteBuffer bb = ByteBuffer.allocate(1024);
- while ((dato = sis.read()) != -1)
+ while ((dato = sis.read()) != -1) {
bb.put((byte) dato);
+ }
bb.flip();
int len = bb.remaining();
String body = "";
@@ -69,6 +70,6 @@ public ResponseEntity getToken(@RequestHeader MultiVal
token.setAccess_token("1111111222222333334444455555666677788899");
token.setExpires_in(10);
token.setToken_type("Emnulado");
- return new ResponseEntity(token, HttpStatus.OK);
+ return new ResponseEntity<>(token, HttpStatus.OK);
}
}
diff --git a/server.app/src/main/java/cl/jonnattan/emulator/controllers/AppController.java b/server.app/src/main/java/cl/jonnattan/emulator/controllers/AppController.java
index fe3060f..156c359 100644
--- a/server.app/src/main/java/cl/jonnattan/emulator/controllers/AppController.java
+++ b/server.app/src/main/java/cl/jonnattan/emulator/controllers/AppController.java
@@ -2,10 +2,8 @@
import cl.jonnattan.emulator.dto.AppListConfigurationDTOResponse;
-import cl.jonnattan.emulator.dto.ints.IEmulator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
@@ -25,20 +23,23 @@
* Controller de configuraci'on de emulador
* Sirve para configurar como queremos que respondan los servicios
* ac'a definidos
- *
+ *
* @author Jonnattan Griffiths
* @since Programa EMULADOR
* @version 1.0 del 22-06-2020
- *
+ *
*/
@RestController
@RequestMapping("/config")
public class AppController {
private static final Logger logger = LoggerFactory.getLogger(AppController.class);
-
- @Autowired
- private IConfigurations configService;
+
+ private final IConfigurations configService;
+
+ public AppController(IConfigurations configService) {
+ this.configService = configService;
+ }
@PostMapping(value = "/update")
public ResponseEntity update(@Valid @RequestBody AppConfigurationRequestDTO request) {
@@ -82,16 +83,16 @@ public ResponseEntity save(@Valid @RequestBody AppConfigurationRequestDT
return new ResponseEntity<>(success, status);
}
- @GetMapping(value = "/list")
- public ResponseEntity list(){
- logger.info(UtilConst.LINE);
- HttpStatus status = HttpStatus.OK;
- AppListConfigurationDTOResponse response = null;
- try {
- response = configService.getConfigurations();
- } catch (ConfException e) {
- status = e.getStatus();
- }
- return new ResponseEntity(response, status);
- }
+ @GetMapping(value = "/list")
+ public ResponseEntity list(){
+ logger.info(UtilConst.LINE);
+ HttpStatus status = HttpStatus.OK;
+ AppListConfigurationDTOResponse response = null;
+ try {
+ response = configService.getConfigurations();
+ } catch (ConfException e) {
+ status = e.getStatus();
+ }
+ return new ResponseEntity<>(response, status);
+ }
}
diff --git a/server.app/src/main/java/cl/jonnattan/emulator/controllers/CetipaController.java b/server.app/src/main/java/cl/jonnattan/emulator/controllers/CetipaController.java
index d48d96a..2fb1c20 100644
--- a/server.app/src/main/java/cl/jonnattan/emulator/controllers/CetipaController.java
+++ b/server.app/src/main/java/cl/jonnattan/emulator/controllers/CetipaController.java
@@ -1,10 +1,9 @@
package cl.jonnattan.emulator.controllers;
import java.util.UUID;
-import java.util.logging.Logger;
-
-import org.springframework.beans.factory.annotation.Autowired;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -32,39 +31,41 @@
import cl.jonnattan.emulator.interfaces.ITrm;
import cl.jonnattan.emulator.utils.ConfException;
import cl.jonnattan.emulator.utils.EmulatorException;
+import cl.jonnattan.emulator.utils.UtilConst;
import jakarta.validation.Valid;
/**
* Controlles principal de emulador
- *
+ *
* @author Jonnattan Griffiths
* @since Programa EMULADOR
* @version 1.0 del 22-06-2020
- *
+ *
*/
@RestController
@RequestMapping("/")
public class CetipaController {
- private static final Logger logger = Logger.getLogger(CetipaController.class.getName());
-
- @Autowired
- private ITransactions transactionService;
- @Autowired
- private ITrm trmService;
+ private static final Logger logger = LoggerFactory.getLogger(CetipaController.class);
- @Autowired
- private IPrm prmService;
+ private final ITransactions transactionService;
+ private final ITrm trmService;
+ private final IPrm prmService;
+ private final ICard cardService;
+ private final IConfigurations configService;
- @Autowired
- private ICard cardService;
-
- @Autowired
- private IConfigurations configService;
+ public CetipaController(ITransactions transactionService, ITrm trmService, IPrm prmService, ICard cardService,
+ IConfigurations configService) {
+ this.transactionService = transactionService;
+ this.trmService = trmService;
+ this.prmService = prmService;
+ this.cardService = cardService;
+ this.configService = configService;
+ }
/**
* Autorizar transaccion
- *
+ *
* @param transaction
* @param headersRx
* @return
@@ -102,8 +103,8 @@ public ResponseEntity reverse(@Valid @RequestBody EdrPaymentReverseRe
IEmulator response = null;
HttpHeaders headersTx = new HttpHeaders();
// Se pasa el mismo requestid
- String id = headersRx.get("requestid").get(0);
- headersTx.add("requestid", id);
+ String id = headersRx.get(UtilConst.REQUEST_ID).get(0);
+ headersTx.add(UtilConst.REQUEST_ID, id);
HttpStatus status = HttpStatus.OK;
try {
configService.evaluateEndpoint("/pay/ptm/v1/voids");
@@ -125,7 +126,7 @@ public ResponseEntity reverse(@Valid @RequestBody EdrPaymentReverseRe
/**
* Enrola una tarjeta en apitec.
- *
+ *
* @param request
* @param headersRx
* @return
@@ -152,11 +153,11 @@ public ResponseEntity deviceEnroll(@Valid @RequestBody EdrTokenEnroll
((ErrorData) response).setMessage(e.getMessage());
}
- return new ResponseEntity(response, headersTx, status);
+ return new ResponseEntity<>(response, headersTx, status);
}
/**
- *
+ *
* @param request
* @param headersRx
* @return
@@ -183,11 +184,11 @@ public ResponseEntity deviceSearch(@Valid @RequestBody EdrTokenGetDig
((ErrorData) response).setMessage(e.getMessage());
}
- return new ResponseEntity(response, headersTx, status);
+ return new ResponseEntity<>(response, headersTx, status);
}
/**
- *
+ *
* @param request
* @param headersRx
* @return
@@ -212,11 +213,11 @@ public ResponseEntity getToken(@PathVariable String token, @RequestHe
((ErrorData) response).setCode(e.getCode());
((ErrorData) response).setMessage(e.getMessage());
}
- return new ResponseEntity(response, headersTx, status);
+ return new ResponseEntity<>(response, headersTx, status);
}
/**
- *
+ *
* @param request
* @param headersRx
* @return
@@ -228,20 +229,20 @@ public ResponseEntity getAcquire(@PathVariable String token, @RequestHea
HttpHeaders headersTx = new HttpHeaders();
HttpStatus status = HttpStatus.OK;
- String requestid = headerRx.get("requestid").get(0);
- String client_id = headerRx.get("client_id").get(0);
- String access_token = headerRx.get("access_token").get(0);
+ String requestid = headerRx.get(UtilConst.REQUEST_ID).get(0);
+ String clientId = headerRx.get(UtilConst.CLIENT_ID).get(0);
+ String accessToken = headerRx.get(UtilConst.ACCESS_TOKEN).get(0);
- logger.info("requestid : " + requestid);
- logger.info("client_id : " + client_id);
- logger.info("access_token: " + access_token);
- logger.info("token : " + token);
+ logger.info("requestid : {}", requestid);
+ logger.info("client_id : {}", clientId);
+ logger.info("access_token: {}", accessToken);
+ logger.info("token : {}", token);
- return new ResponseEntity("OK", headersTx, status);
+ return new ResponseEntity<>("OK", headersTx, status);
}
/**
- *
+ *
* @param requestor
* @param request
* @param header
@@ -260,12 +261,13 @@ public ResponseEntity logingout(@PathVariable String requestor,
// Este token es muy importante. Apitec lo cambi'o hace poco a un valor m'as
// grande
- String accessToken = "EMULATOR-PAYMENT";
- for (int i = 0; i < 100; i++)
- accessToken += "-" + UUID.randomUUID().toString();
+ StringBuilder accessToken = new StringBuilder("EMULATOR-PAYMENT");
+ for (int i = 0; i < 100; i++) {
+ accessToken.append("-").append(UUID.randomUUID().toString());
+ }
- headersTx.add("access_token", accessToken);
- logger.info("PRM Response Header[access_token]: " + accessToken);
+ headersTx.add(UtilConst.ACCESS_TOKEN, accessToken.toString());
+ logger.info("PRM Response Header[access_token]: {}", accessToken);
} catch (EmulatorException e) {
status = HttpStatus.CONFLICT;
response = new ErrorData();
@@ -277,11 +279,11 @@ public ResponseEntity logingout(@PathVariable String requestor,
((ErrorData) response).setCode(e.getCode());
((ErrorData) response).setMessage(e.getMessage());
}
- return new ResponseEntity(response, headersTx, status);
+ return new ResponseEntity<>(response, headersTx, status);
}
/**
- *
+ *
* @param requestor
* @param request
* @param headersRx
@@ -297,15 +299,16 @@ public ResponseEntity logingout(@PathVariable String requestor,
try {
configService.evaluateEndpoint("/tsp/trm/v1/requestors/{requestor}/logon");
response = trmService.logon(requestor, headersRx, request);
-
-
- String accessToken = "EMULATOR-TOKEN";
- for (int i = 0; i < 100; i++)
- accessToken += "-" + UUID.randomUUID().toString();
- headersTx.add("access_token", accessToken);
- logger.info("TRM Response Header[access_token]: " + accessToken);
-
+
+ StringBuilder accessToken = new StringBuilder("EMULATOR-TOKEN");
+ for (int i = 0; i < 100; i++) {
+ accessToken.append("-").append(UUID.randomUUID().toString());
+ }
+
+ headersTx.add(UtilConst.ACCESS_TOKEN, accessToken.toString());
+ logger.info("TRM Response Header[access_token]: {}", accessToken);
+
} catch (EmulatorException e) {
status = HttpStatus.CONFLICT;
response = new ErrorData();
@@ -317,12 +320,12 @@ public ResponseEntity logingout(@PathVariable String requestor,
((ErrorData) response).setCode(e.getCode());
((ErrorData) response).setMessage(e.getMessage());
}
- return new ResponseEntity(response, headersTx, status);
+ return new ResponseEntity<>(response, headersTx, status);
}
/**
* Obtiene los datos relacionados con el criptograma
- *
+ *
* @param token
* @param request
* @param headersRx
@@ -349,7 +352,7 @@ public ResponseEntity cryptograms(@PathVariable String token,
((ErrorData) response).setCode(e.getCode());
((ErrorData) response).setMessage(e.getMessage());
}
- return new ResponseEntity(response, headersTx, status);
+ return new ResponseEntity<>(response, headersTx, status);
}
}
diff --git a/server.app/src/main/java/cl/jonnattan/emulator/controllers/CxpController.java b/server.app/src/main/java/cl/jonnattan/emulator/controllers/CxpController.java
index 04d51dc..fb749bd 100644
--- a/server.app/src/main/java/cl/jonnattan/emulator/controllers/CxpController.java
+++ b/server.app/src/main/java/cl/jonnattan/emulator/controllers/CxpController.java
@@ -1,8 +1,7 @@
package cl.jonnattan.emulator.controllers;
-import java.util.logging.Logger;
-
-import org.springframework.beans.factory.annotation.Autowired;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -20,18 +19,23 @@
/**
* Controlles de conf de emulador
- *
+ *
* @author Jonnattan Griffiths
- * @since Programa EMULADOR
+ * @since Programa EMULADOR
* @version 1.0 del 11-05-2021
- *
+ *
*/
@RestController
@RequestMapping("/cxp")
public class CxpController {
- private static final Logger logger = Logger.getLogger(CxpController.class.getName());
- @Autowired
- private ICxp cxpService;
+
+ private static final Logger logger = LoggerFactory.getLogger(CxpController.class);
+
+ private final ICxp cxpService;
+
+ public CxpController(ICxp cxpService) {
+ this.cxpService = cxpService;
+ }
@PostMapping(value = "/**")
public ResponseEntity postCxp(HttpServletRequest request, @RequestHeader HttpHeaders headerRx) {
diff --git a/server.app/src/main/java/cl/jonnattan/emulator/controllers/EdrController.java b/server.app/src/main/java/cl/jonnattan/emulator/controllers/EdrController.java
index f72c4f7..1dc4e92 100644
--- a/server.app/src/main/java/cl/jonnattan/emulator/controllers/EdrController.java
+++ b/server.app/src/main/java/cl/jonnattan/emulator/controllers/EdrController.java
@@ -1,8 +1,7 @@
package cl.jonnattan.emulator.controllers;
-import java.util.logging.Logger;
-
-import org.springframework.beans.factory.annotation.Autowired;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
@@ -20,27 +19,30 @@
/**
* Controlles principal de emulador
- *
+ *
* @author Jonnattan Griffiths
- * @since Programa EMULADOR
+ * @since Programa EMULADOR
* @version 1.0 del 22-06-2020
- *
+ *
*/
@RestController
@RequestMapping("/edr")
public class EdrController {
- private static final Logger logger = Logger.getLogger(EdrController.class.getName());
- @Autowired
- private IEdr edrService;
+ private static final Logger logger = LoggerFactory.getLogger(EdrController.class);
+
+ private final IEdr edrService;
+ private final IConfigurations configService;
- @Autowired
- private IConfigurations configService;
+ public EdrController(IEdr edrService, IConfigurations configService) {
+ this.edrService = edrService;
+ this.configService = configService;
+ }
@PostMapping(path = "/login/tickettest", consumes = { MediaType.APPLICATION_FORM_URLENCODED_VALUE }, produces = { MediaType.APPLICATION_FORM_URLENCODED_VALUE })
public ResponseEntity handleNonBrowserSubmissions(@RequestHeader MultiValueMap headersRx) {
logger.info("****************************/login/ticket****************************");
- logger.info("REALM: " + headersRx.get("realm"));
+ logger.info("REALM: {}", headersRx.get("realm"));
return new ResponseEntity<>("Thank you for submitting feedback", HttpStatus.OK);
}
diff --git a/server.app/src/main/java/cl/jonnattan/emulator/controllers/EdrEgdController.java b/server.app/src/main/java/cl/jonnattan/emulator/controllers/EdrEgdController.java
index d45075b..3510cf8 100644
--- a/server.app/src/main/java/cl/jonnattan/emulator/controllers/EdrEgdController.java
+++ b/server.app/src/main/java/cl/jonnattan/emulator/controllers/EdrEgdController.java
@@ -1,9 +1,7 @@
package cl.jonnattan.emulator.controllers;
-import java.util.logging.Logger;
-
-
-import org.springframework.beans.factory.annotation.Autowired;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -21,22 +19,25 @@
/**
* Controlles principal de emulador
- *
+ *
* @author Jonnattan Griffiths
* @since Programa EMULADOR
* @version 1.0 del 22-06-2020
- *
+ *
*/
@RestController
@RequestMapping("/")
public class EdrEgdController {
- private static final Logger logger = Logger.getLogger(EdrEgdController.class.getName());
- @Autowired
- private ICard cardService;
+ private static final Logger logger = LoggerFactory.getLogger(EdrEgdController.class);
- @Autowired
- private IConfigurations configService;
+ private final ICard cardService;
+ private final IConfigurations configService;
+
+ public EdrEgdController(ICard cardService, IConfigurations configService) {
+ this.cardService = cardService;
+ this.configService = configService;
+ }
@RequestMapping(value = "/api/v1/foods/cards/**")
public ResponseEntity edgCardSearch(HttpServletRequest request, @RequestHeader HttpHeaders headerRx) {
@@ -59,7 +60,7 @@ public ResponseEntity edgCardSearch(HttpServletRequest request, @Requ
((ErrorData) response).setCode(e.getCode());
((ErrorData) response).setMessage(e.getMessage());
}
- return new ResponseEntity(response, headersTx, status);
+ return new ResponseEntity<>(response, headersTx, status);
}
}
diff --git a/server.app/src/main/java/cl/jonnattan/emulator/controllers/PageController.java b/server.app/src/main/java/cl/jonnattan/emulator/controllers/PageController.java
index 3cc2639..26bfb4d 100644
--- a/server.app/src/main/java/cl/jonnattan/emulator/controllers/PageController.java
+++ b/server.app/src/main/java/cl/jonnattan/emulator/controllers/PageController.java
@@ -3,7 +3,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
@@ -25,16 +24,17 @@
import cl.jonnattan.emulator.interfaces.IPage;
import cl.jonnattan.emulator.utils.ConfException;
import cl.jonnattan.emulator.utils.EmulatorException;
+import cl.jonnattan.emulator.utils.UtilConst;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
/**
* Controller para solicitudes desde la web personal
- *
+ *
* @author Jonnattan Griffiths
* @since Programa EMULADOR
* @version 1.0 del 20-02-2023
- *
+ *
*/
@RestController
@RequestMapping("/page")
@@ -42,18 +42,20 @@ public class PageController {
private static final Logger logger = LoggerFactory.getLogger(PageController.class);
- @Autowired
- private IPage pageService;
+ private final IPage pageService;
+ private final IConfigurations configService;
+
+ public PageController(IPage pageService, IConfigurations configService) {
+ this.pageService = pageService;
+ this.configService = configService;
+ }
- @Autowired
- private IConfigurations configService;
@CrossOrigin(origins = "*")
@PostMapping(path = "/users/save", consumes = { MediaType.APPLICATION_FORM_URLENCODED_VALUE }, produces = {
MediaType.TEXT_HTML_VALUE })
-
public ResponseEntity save(@Valid @RequestParam MultiValueMap params,
HttpServletRequest request, @RequestHeader HttpHeaders headers) {
- logger.info("---------------------------------------------------------------------------------------");
+ logger.info(UtilConst.LINE);
HttpStatus status = HttpStatus.OK;
IEmulator response = null;
HttpHeaders headersTx = new HttpHeaders();
diff --git a/server.app/src/main/resources/application-dev.yml b/server.app/src/main/resources/application-dev.yml
index 30b176c..86bcdce 100644
--- a/server.app/src/main/resources/application-dev.yml
+++ b/server.app/src/main/resources/application-dev.yml
@@ -28,8 +28,6 @@ spring:
jackson:
date-format: "yyyy-MM-dd'T'HH:mm:ss"
- serialization:
- WRITE_DATES_WITH_ZONE_ID: true
server:
address: 0.0.0.0
diff --git a/server.app/src/test/java/cl/jonnattan/emulator/controllers/AppCommeControllerTest.java b/server.app/src/test/java/cl/jonnattan/emulator/controllers/AppCommeControllerTest.java
new file mode 100644
index 0000000..07f3445
--- /dev/null
+++ b/server.app/src/test/java/cl/jonnattan/emulator/controllers/AppCommeControllerTest.java
@@ -0,0 +1,75 @@
+package cl.jonnattan.emulator.controllers;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.LinkedMultiValueMap;
+
+import cl.jonnattan.emulator.dto.CommerceMailResponseDTO;
+import cl.jonnattan.emulator.dto.CommerceTokenResponseDTO;
+import jakarta.servlet.ReadListener;
+import jakarta.servlet.ServletInputStream;
+import jakarta.servlet.http.HttpServletRequest;
+
+class AppCommeControllerTest {
+
+ private final AppCommeController controller = new AppCommeController();
+
+ @Test
+ void sendMail_conBody_retornaOK() throws IOException {
+ HttpServletRequest req = mock(HttpServletRequest.class);
+ ByteArrayInputStream bais = new ByteArrayInputStream("{\"a\":1}".getBytes());
+ when(req.getInputStream()).thenReturn(stream(bais));
+
+ ResponseEntity rsp = controller.sendMail(req, new LinkedMultiValueMap<>());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void sendMail_ioError_retornaOK() throws IOException {
+ HttpServletRequest req = mock(HttpServletRequest.class);
+ when(req.getInputStream()).thenThrow(new IOException("boom"));
+
+ ResponseEntity rsp = controller.sendMail(req, new LinkedMultiValueMap<>());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void getToken_retornaTokenConAccessToken() {
+ ResponseEntity rsp = controller.getToken(new LinkedMultiValueMap<>());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ assertNotNull(rsp.getBody().getAccess_token());
+ }
+
+ private ServletInputStream stream(ByteArrayInputStream bais) {
+ return new ServletInputStream() {
+ @Override
+ public int read() {
+ return bais.read();
+ }
+
+ @Override
+ public boolean isFinished() {
+ return bais.available() == 0;
+ }
+
+ @Override
+ public boolean isReady() {
+ return true;
+ }
+
+ @Override
+ public void setReadListener(ReadListener listener) {
+ // noop
+ }
+ };
+ }
+}
diff --git a/server.app/src/test/java/cl/jonnattan/emulator/controllers/AppControllerTest.java b/server.app/src/test/java/cl/jonnattan/emulator/controllers/AppControllerTest.java
new file mode 100644
index 0000000..5980ca3
--- /dev/null
+++ b/server.app/src/test/java/cl/jonnattan/emulator/controllers/AppControllerTest.java
@@ -0,0 +1,101 @@
+package cl.jonnattan.emulator.controllers;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import cl.jonnattan.emulator.dto.AppConfigurationRequestDTO;
+import cl.jonnattan.emulator.dto.AppListConfigurationDTOResponse;
+import cl.jonnattan.emulator.enums.TypeResponse;
+import cl.jonnattan.emulator.interfaces.IConfigurations;
+import cl.jonnattan.emulator.utils.ConfException;
+
+@ExtendWith(MockitoExtension.class)
+class AppControllerTest {
+
+ @Mock
+ private IConfigurations configService;
+
+ @InjectMocks
+ private AppController controller;
+
+ private AppConfigurationRequestDTO req() {
+ AppConfigurationRequestDTO dto = new AppConfigurationRequestDTO();
+ dto.setEndPoint("/x");
+ dto.setError(Boolean.TRUE);
+ dto.setCode("500");
+ dto.setMessage("m");
+ dto.setType(500);
+ return dto;
+ }
+
+ @Test
+ void update_ok_retornaOK() throws ConfException {
+ when(configService.updateConfigurations(any())).thenReturn("ok");
+ ResponseEntity rsp = controller.update(req());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void update_excepcion_retornaStatusDeExcepcion() throws ConfException {
+ when(configService.updateConfigurations(any()))
+ .thenThrow(new ConfException("err", "500", TypeResponse.HTTP_RESPONSE_500));
+ ResponseEntity rsp = controller.update(req());
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, rsp.getStatusCode());
+ }
+
+ @Test
+ void create_ok_retornaOK() throws ConfException {
+ when(configService.createConfigurations(any())).thenReturn("ok");
+ ResponseEntity rsp = controller.create(req());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void create_error_retornaStatusDeExcepcion() throws ConfException {
+ when(configService.createConfigurations(any()))
+ .thenThrow(new ConfException("x", "400", TypeResponse.HTTP_RESPONSE_400));
+ ResponseEntity rsp = controller.create(req());
+ assertEquals(HttpStatus.BAD_REQUEST, rsp.getStatusCode());
+ }
+
+ @Test
+ void save_ok_retornaOK() throws ConfException {
+ when(configService.saveConfigurations(any())).thenReturn("ok");
+ ResponseEntity rsp = controller.save(req());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void save_error_retornaStatusDeExcepcion() throws ConfException {
+ when(configService.saveConfigurations(any()))
+ .thenThrow(new ConfException("x", "409", TypeResponse.HTTP_RESPONSE_409));
+ ResponseEntity rsp = controller.save(req());
+ assertEquals(HttpStatus.CONFLICT, rsp.getStatusCode());
+ }
+
+ @Test
+ void list_ok_retornaOK() throws ConfException {
+ when(configService.getConfigurations()).thenReturn(new AppListConfigurationDTOResponse());
+ ResponseEntity rsp = controller.list();
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ assertNotNull(rsp.getBody());
+ }
+
+ @Test
+ void list_error_retornaStatusDeExcepcion() throws ConfException {
+ when(configService.getConfigurations())
+ .thenThrow(new ConfException("x", "503", TypeResponse.HTTP_RESPONSE_503));
+ ResponseEntity rsp = controller.list();
+ assertEquals(HttpStatus.SERVICE_UNAVAILABLE, rsp.getStatusCode());
+ }
+}
diff --git a/server.app/src/test/java/cl/jonnattan/emulator/controllers/CetipaControllerTest.java b/server.app/src/test/java/cl/jonnattan/emulator/controllers/CetipaControllerTest.java
new file mode 100644
index 0000000..77b56c8
--- /dev/null
+++ b/server.app/src/test/java/cl/jonnattan/emulator/controllers/CetipaControllerTest.java
@@ -0,0 +1,202 @@
+package cl.jonnattan.emulator.controllers;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import cl.jonnattan.emulator.dto.EdrPayAuthorizeRequestDTO;
+import cl.jonnattan.emulator.dto.EdrPaymentAuthorizeResponseDTO;
+import cl.jonnattan.emulator.dto.EdrPaymentCreateCryptogramRequestDTO;
+import cl.jonnattan.emulator.dto.EdrPaymentCreateCryptogramResponseDTO;
+import cl.jonnattan.emulator.dto.EdrPaymentLogonRequestDTO;
+import cl.jonnattan.emulator.dto.EdrPaymentLogonResponseDTO;
+import cl.jonnattan.emulator.dto.EdrPaymentReverseRequestDTO;
+import cl.jonnattan.emulator.dto.EdrPaymentReverseResponseDTO;
+import cl.jonnattan.emulator.dto.EdrTokenEnrollResponseDTO;
+import cl.jonnattan.emulator.dto.EdrTokenEnrollmentRequestDTO;
+import cl.jonnattan.emulator.dto.EdrTokenGetDigitalPanRequestDTO;
+import cl.jonnattan.emulator.dto.EdrTokenGetDigitalPanResponseDTO;
+import cl.jonnattan.emulator.dto.EdrTokenGetTokenResponseDTO;
+import cl.jonnattan.emulator.dto.EdrTokenLogonRequestDTO;
+import cl.jonnattan.emulator.dto.EdrTokenLogonResponseDTO;
+import cl.jonnattan.emulator.dto.ints.IEmulator;
+import cl.jonnattan.emulator.enums.TypeResponse;
+import cl.jonnattan.emulator.interfaces.ICard;
+import cl.jonnattan.emulator.interfaces.IConfigurations;
+import cl.jonnattan.emulator.interfaces.IPrm;
+import cl.jonnattan.emulator.interfaces.ITransactions;
+import cl.jonnattan.emulator.interfaces.ITrm;
+import cl.jonnattan.emulator.utils.ConfException;
+import cl.jonnattan.emulator.utils.EmulatorException;
+import cl.jonnattan.emulator.utils.UtilConst;
+
+@ExtendWith(MockitoExtension.class)
+class CetipaControllerTest {
+
+ @Mock
+ private ITransactions transactionService;
+ @Mock
+ private ITrm trmService;
+ @Mock
+ private IPrm prmService;
+ @Mock
+ private ICard cardService;
+ @Mock
+ private IConfigurations configService;
+
+ @InjectMocks
+ private CetipaController controller;
+
+ private HttpHeaders headersConRequestId() {
+ HttpHeaders h = new HttpHeaders();
+ h.put(UtilConst.REQUEST_ID, Collections.singletonList("RX-1"));
+ h.put(UtilConst.CLIENT_ID, Collections.singletonList("CLT"));
+ h.put(UtilConst.ACCESS_TOKEN, Collections.singletonList("TKN"));
+ return h;
+ }
+
+ @Test
+ void authorizations_ok_retornaOK() throws Exception {
+ when(transactionService.createTransaction(any(), any())).thenReturn(new EdrPaymentAuthorizeResponseDTO());
+ ResponseEntity rsp = controller.authorizations(new EdrPayAuthorizeRequestDTO(), new HttpHeaders());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void authorizations_emulatorException_retornaConflict() throws Exception {
+ when(transactionService.createTransaction(any(), any())).thenThrow(new EmulatorException("e", "500"));
+ ResponseEntity rsp = controller.authorizations(new EdrPayAuthorizeRequestDTO(), new HttpHeaders());
+ assertEquals(HttpStatus.CONFLICT, rsp.getStatusCode());
+ }
+
+ @Test
+ void authorizations_confException_retornaStatusDeExcepcion() throws Exception {
+ doThrow(new ConfException("e", "500", TypeResponse.HTTP_RESPONSE_500)).when(configService)
+ .evaluateEndpoint(anyString());
+ ResponseEntity rsp = controller.authorizations(new EdrPayAuthorizeRequestDTO(), new HttpHeaders());
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, rsp.getStatusCode());
+ }
+
+ @Test
+ void reverse_ok_retornaOK() throws Exception {
+ when(transactionService.reverseTransaction(any(), any())).thenReturn(new EdrPaymentReverseResponseDTO());
+ ResponseEntity rsp = controller.reverse(new EdrPaymentReverseRequestDTO(), headersConRequestId());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void reverse_emulatorException_retornaConflict() throws Exception {
+ when(transactionService.reverseTransaction(any(), any())).thenThrow(new EmulatorException("e", "500"));
+ ResponseEntity rsp = controller.reverse(new EdrPaymentReverseRequestDTO(), headersConRequestId());
+ assertEquals(HttpStatus.CONFLICT, rsp.getStatusCode());
+ }
+
+ @Test
+ void deviceEnroll_ok_retornaOK() throws Exception {
+ when(cardService.enrollDevice(any(), any())).thenReturn(new EdrTokenEnrollResponseDTO());
+ ResponseEntity rsp = controller.deviceEnroll(new EdrTokenEnrollmentRequestDTO(), new HttpHeaders());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void deviceEnroll_error_retornaConflict() throws Exception {
+ when(cardService.enrollDevice(any(), any())).thenThrow(new EmulatorException("x"));
+ ResponseEntity rsp = controller.deviceEnroll(new EdrTokenEnrollmentRequestDTO(), new HttpHeaders());
+ assertEquals(HttpStatus.CONFLICT, rsp.getStatusCode());
+ }
+
+ @Test
+ void deviceSearch_ok_retornaOK() throws Exception {
+ when(cardService.cardSearch(any(), any())).thenReturn(new EdrTokenGetDigitalPanResponseDTO());
+ ResponseEntity rsp = controller.deviceSearch(new EdrTokenGetDigitalPanRequestDTO(), new HttpHeaders());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void deviceSearch_error_retornaStatusDeExcepcion() throws Exception {
+ doThrow(new ConfException("x", "409", TypeResponse.HTTP_RESPONSE_409)).when(configService)
+ .evaluateEndpoint(anyString());
+ ResponseEntity rsp = controller.deviceSearch(new EdrTokenGetDigitalPanRequestDTO(), new HttpHeaders());
+ assertEquals(HttpStatus.CONFLICT, rsp.getStatusCode());
+ }
+
+ @Test
+ void getToken_ok_retornaOK() throws Exception {
+ when(cardService.getToken(any(), any())).thenReturn(new EdrTokenGetTokenResponseDTO());
+ ResponseEntity rsp = controller.getToken("TKN", new HttpHeaders());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void getToken_error_retornaConflict() throws Exception {
+ when(cardService.getToken(any(), any())).thenThrow(new EmulatorException("e"));
+ ResponseEntity rsp = controller.getToken("TKN", new HttpHeaders());
+ assertEquals(HttpStatus.CONFLICT, rsp.getStatusCode());
+ }
+
+ @Test
+ void getAcquire_ok_retornaOK() {
+ ResponseEntity rsp = controller.getAcquire("TKN", headersConRequestId());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ assertNotNull(rsp.getBody());
+ }
+
+ @Test
+ void logingoutPrm_ok_retornaOK() throws Exception {
+ when(prmService.logon(any(), any(), any())).thenReturn(new EdrPaymentLogonResponseDTO());
+ ResponseEntity rsp = controller.logingout("R1", new EdrPaymentLogonRequestDTO(), new HttpHeaders());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void logingoutPrm_error_retornaConflict() throws Exception {
+ when(prmService.logon(any(), any(), any())).thenThrow(new EmulatorException("x"));
+ ResponseEntity rsp = controller.logingout("R1", new EdrPaymentLogonRequestDTO(), new HttpHeaders());
+ assertEquals(HttpStatus.CONFLICT, rsp.getStatusCode());
+ }
+
+ @Test
+ void logingoutTrm_ok_retornaOK() throws Exception {
+ when(trmService.logon(any(), any(), any())).thenReturn(new EdrTokenLogonResponseDTO());
+ ResponseEntity rsp = controller.logingout("R1", new EdrTokenLogonRequestDTO(), new HttpHeaders());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void logingoutTrm_error_retornaConflict() throws Exception {
+ when(trmService.logon(any(), any(), any())).thenThrow(new EmulatorException("x"));
+ ResponseEntity rsp = controller.logingout("R1", new EdrTokenLogonRequestDTO(), new HttpHeaders());
+ assertEquals(HttpStatus.CONFLICT, rsp.getStatusCode());
+ }
+
+ @Test
+ void cryptograms_ok_retornaOK() throws Exception {
+ when(transactionService.createCriptogram(any(), any(), any()))
+ .thenReturn(new EdrPaymentCreateCryptogramResponseDTO());
+ ResponseEntity rsp = controller.cryptograms("TKN", new EdrPaymentCreateCryptogramRequestDTO(),
+ new HttpHeaders());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void cryptograms_error_retornaConflict() throws Exception {
+ when(transactionService.createCriptogram(any(), any(), any())).thenThrow(new EmulatorException("e"));
+ ResponseEntity rsp = controller.cryptograms("TKN", new EdrPaymentCreateCryptogramRequestDTO(),
+ new HttpHeaders());
+ assertEquals(HttpStatus.CONFLICT, rsp.getStatusCode());
+ }
+}
diff --git a/server.app/src/test/java/cl/jonnattan/emulator/controllers/CxpControllerTest.java b/server.app/src/test/java/cl/jonnattan/emulator/controllers/CxpControllerTest.java
new file mode 100644
index 0000000..e22598d
--- /dev/null
+++ b/server.app/src/test/java/cl/jonnattan/emulator/controllers/CxpControllerTest.java
@@ -0,0 +1,67 @@
+package cl.jonnattan.emulator.controllers;
+
+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;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import cl.jonnattan.emulator.dto.cxp.CxpResponseDTO;
+import cl.jonnattan.emulator.dto.cxp.ICxpResponse;
+import cl.jonnattan.emulator.interfaces.ICxp;
+import cl.jonnattan.emulator.utils.EmulatorException;
+import jakarta.servlet.http.HttpServletRequest;
+
+@ExtendWith(MockitoExtension.class)
+class CxpControllerTest {
+
+ @Mock
+ private ICxp cxpService;
+
+ @InjectMocks
+ private CxpController controller;
+
+ @Test
+ void postCxp_ok_retornaOK() throws Exception {
+ HttpServletRequest req = mock(HttpServletRequest.class);
+ when(cxpService.processPostRequest(any(), any())).thenReturn(new CxpResponseDTO());
+
+ ResponseEntity rsp = controller.postCxp(req, new HttpHeaders());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void postCxp_error_retornaConflict() throws Exception {
+ HttpServletRequest req = mock(HttpServletRequest.class);
+ when(cxpService.processPostRequest(any(), any())).thenThrow(new EmulatorException("err"));
+
+ ResponseEntity rsp = controller.postCxp(req, new HttpHeaders());
+ assertEquals(HttpStatus.CONFLICT, rsp.getStatusCode());
+ }
+
+ @Test
+ void getCxp_ok_retornaOK() throws Exception {
+ HttpServletRequest req = mock(HttpServletRequest.class);
+ when(cxpService.processGetRequest(any(), any())).thenReturn("ok");
+
+ ResponseEntity rsp = controller.getCxp(req, new HttpHeaders());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void getCxp_error_retornaConflict() throws Exception {
+ HttpServletRequest req = mock(HttpServletRequest.class);
+ when(cxpService.processGetRequest(any(), any())).thenThrow(new EmulatorException("err"));
+
+ ResponseEntity rsp = controller.getCxp(req, new HttpHeaders());
+ assertEquals(HttpStatus.CONFLICT, rsp.getStatusCode());
+ }
+}
diff --git a/server.app/src/test/java/cl/jonnattan/emulator/controllers/EdrControllerTest.java b/server.app/src/test/java/cl/jonnattan/emulator/controllers/EdrControllerTest.java
new file mode 100644
index 0000000..134794d
--- /dev/null
+++ b/server.app/src/test/java/cl/jonnattan/emulator/controllers/EdrControllerTest.java
@@ -0,0 +1,93 @@
+package cl.jonnattan.emulator.controllers;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+
+import cl.jonnattan.emulator.enums.TypeResponse;
+import cl.jonnattan.emulator.interfaces.IConfigurations;
+import cl.jonnattan.emulator.interfaces.IEdr;
+import cl.jonnattan.emulator.utils.ConfException;
+import cl.jonnattan.emulator.utils.EmulatorException;
+
+@ExtendWith(MockitoExtension.class)
+class EdrControllerTest {
+
+ @Mock
+ private IEdr edrService;
+ @Mock
+ private IConfigurations configService;
+
+ @InjectMocks
+ private EdrController controller;
+
+ private MultiValueMap headers() {
+ MultiValueMap h = new LinkedMultiValueMap<>();
+ h.put("realm", Collections.singletonList("test"));
+ return h;
+ }
+
+ @Test
+ void handleNonBrowserSubmissions_retornaOk() {
+ ResponseEntity rsp = controller.handleNonBrowserSubmissions(headers());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void loginTicket_ok_retornaOK() throws Exception {
+ when(edrService.loginEdenred(any())).thenReturn("TOKEN");
+ ResponseEntity rsp = controller.loginTicket(headers());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void loginTicket_emulatorException_retornaConflict() throws Exception {
+ when(edrService.loginEdenred(any())).thenThrow(new EmulatorException("err"));
+ ResponseEntity rsp = controller.loginTicket(headers());
+ assertEquals(HttpStatus.CONFLICT, rsp.getStatusCode());
+ }
+
+ @Test
+ void loginTicket_confException_retornaStatusDeExcepcion() throws Exception {
+ doThrow(new ConfException("x", "500", TypeResponse.HTTP_RESPONSE_500)).when(configService)
+ .evaluateEndpoint(anyString());
+ ResponseEntity rsp = controller.loginTicket(headers());
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, rsp.getStatusCode());
+ }
+
+ @Test
+ void loginJunaeb_ok_retornaOK() throws Exception {
+ when(edrService.loginEdenred(any())).thenReturn("TOKEN");
+ ResponseEntity rsp = controller.loginJunaeb(headers());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void loginJunaeb_error_retornaConflict() throws Exception {
+ when(edrService.loginEdenred(any())).thenThrow(new EmulatorException("err"));
+ ResponseEntity rsp = controller.loginJunaeb(headers());
+ assertEquals(HttpStatus.CONFLICT, rsp.getStatusCode());
+ }
+
+ @Test
+ void loginJunaeb_confException_retornaStatusDeExcepcion() throws Exception {
+ doThrow(new ConfException("x", "503", TypeResponse.HTTP_RESPONSE_503)).when(configService)
+ .evaluateEndpoint(anyString());
+ ResponseEntity rsp = controller.loginJunaeb(headers());
+ assertEquals(HttpStatus.SERVICE_UNAVAILABLE, rsp.getStatusCode());
+ }
+}
diff --git a/server.app/src/test/java/cl/jonnattan/emulator/controllers/EdrEgdControllerTest.java b/server.app/src/test/java/cl/jonnattan/emulator/controllers/EdrEgdControllerTest.java
new file mode 100644
index 0000000..b371f96
--- /dev/null
+++ b/server.app/src/test/java/cl/jonnattan/emulator/controllers/EdrEgdControllerTest.java
@@ -0,0 +1,66 @@
+package cl.jonnattan.emulator.controllers;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import cl.jonnattan.emulator.dto.ints.IEmulator;
+import cl.jonnattan.emulator.dto.user.UserListDTOResponse;
+import cl.jonnattan.emulator.enums.TypeResponse;
+import cl.jonnattan.emulator.interfaces.ICard;
+import cl.jonnattan.emulator.interfaces.IConfigurations;
+import cl.jonnattan.emulator.utils.ConfException;
+import cl.jonnattan.emulator.utils.EmulatorException;
+import jakarta.servlet.http.HttpServletRequest;
+
+@ExtendWith(MockitoExtension.class)
+class EdrEgdControllerTest {
+
+ @Mock
+ private ICard cardService;
+ @Mock
+ private IConfigurations configService;
+
+ @InjectMocks
+ private EdrEgdController controller;
+
+ @Test
+ void edgCardSearch_ok_retornaOK() throws Exception {
+ HttpServletRequest req = mock(HttpServletRequest.class);
+ when(cardService.processTNP(any(), any())).thenReturn(new UserListDTOResponse());
+
+ ResponseEntity rsp = controller.edgCardSearch(req, new HttpHeaders());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void edgCardSearch_emulatorException_retornaConflict() throws Exception {
+ HttpServletRequest req = mock(HttpServletRequest.class);
+ when(cardService.processTNP(any(), any())).thenThrow(new EmulatorException("e", "5000"));
+
+ ResponseEntity rsp = controller.edgCardSearch(req, new HttpHeaders());
+ assertEquals(HttpStatus.CONFLICT, rsp.getStatusCode());
+ }
+
+ @Test
+ void edgCardSearch_confException_retornaStatusDeExcepcion() throws Exception {
+ HttpServletRequest req = mock(HttpServletRequest.class);
+ doThrow(new ConfException("e", "500", TypeResponse.HTTP_RESPONSE_500)).when(configService)
+ .evaluateEndpoint(anyString());
+
+ ResponseEntity rsp = controller.edgCardSearch(req, new HttpHeaders());
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, rsp.getStatusCode());
+ }
+}
diff --git a/server.app/src/test/java/cl/jonnattan/emulator/controllers/PageControllerTest.java b/server.app/src/test/java/cl/jonnattan/emulator/controllers/PageControllerTest.java
new file mode 100644
index 0000000..ddf0a84
--- /dev/null
+++ b/server.app/src/test/java/cl/jonnattan/emulator/controllers/PageControllerTest.java
@@ -0,0 +1,108 @@
+package cl.jonnattan.emulator.controllers;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+
+import cl.jonnattan.emulator.dto.ErrorData;
+import cl.jonnattan.emulator.dto.ints.IEmulator;
+import cl.jonnattan.emulator.dto.user.UserListDTOResponse;
+import cl.jonnattan.emulator.enums.TypeResponse;
+import cl.jonnattan.emulator.interfaces.IConfigurations;
+import cl.jonnattan.emulator.interfaces.IPage;
+import cl.jonnattan.emulator.utils.ConfException;
+import cl.jonnattan.emulator.utils.EmulatorException;
+import jakarta.servlet.http.HttpServletRequest;
+
+@ExtendWith(MockitoExtension.class)
+class PageControllerTest {
+
+ @Mock
+ private IPage pageService;
+ @Mock
+ private IConfigurations configService;
+
+ @InjectMocks
+ private PageController controller;
+
+ @Test
+ void save_ok_retornaOK() throws Exception {
+ HttpServletRequest req = mock(HttpServletRequest.class);
+ when(req.getRequestURI()).thenReturn("/page/users/save");
+ when(pageService.save(any(), any())).thenReturn(new UserListDTOResponse());
+
+ MultiValueMap params = new LinkedMultiValueMap<>();
+ ResponseEntity rsp = controller.save(params, req, new HttpHeaders());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void save_emulatorException_retornaConflict() throws Exception {
+ HttpServletRequest req = mock(HttpServletRequest.class);
+ when(req.getRequestURI()).thenReturn("/page/users/save");
+ when(pageService.save(any(), any())).thenThrow(new EmulatorException("x", "500"));
+
+ MultiValueMap params = new LinkedMultiValueMap<>();
+ ResponseEntity rsp = controller.save(params, req, new HttpHeaders());
+ assertEquals(HttpStatus.CONFLICT, rsp.getStatusCode());
+ }
+
+ @Test
+ void save_confException_retornaStatusDeExcepcion() throws Exception {
+ HttpServletRequest req = mock(HttpServletRequest.class);
+ when(req.getRequestURI()).thenReturn("/page/users/save");
+ doThrow(new ConfException("x", "400", TypeResponse.HTTP_RESPONSE_400)).when(configService)
+ .evaluateEndpoint(anyString());
+
+ MultiValueMap params = new LinkedMultiValueMap<>();
+ ResponseEntity rsp = controller.save(params, req, new HttpHeaders());
+ assertEquals(HttpStatus.BAD_REQUEST, rsp.getStatusCode());
+ }
+
+ @Test
+ void getUsers_ok_retornaOK() throws Exception {
+ HttpServletRequest req = mock(HttpServletRequest.class);
+ when(req.getRequestURI()).thenReturn("/page/users");
+ when(pageService.getUsers(any())).thenReturn(new UserListDTOResponse());
+
+ ResponseEntity rsp = controller.getUsers(req, new HttpHeaders());
+ assertEquals(HttpStatus.OK, rsp.getStatusCode());
+ }
+
+ @Test
+ void getUsers_error_retornaConflict() throws Exception {
+ HttpServletRequest req = mock(HttpServletRequest.class);
+ when(req.getRequestURI()).thenReturn("/page/users");
+ when(pageService.getUsers(any())).thenThrow(new EmulatorException("x"));
+
+ ResponseEntity rsp = controller.getUsers(req, new HttpHeaders());
+ assertEquals(HttpStatus.CONFLICT, rsp.getStatusCode());
+ }
+
+ @Test
+ void handleException_emulatorException_retornaConflictConErrorData() {
+ ResponseEntity
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
commons-codec
commons-codec
diff --git a/server.services/src/main/java/cl/jonnattan/emulator/services/AppConfigService.java b/server.services/src/main/java/cl/jonnattan/emulator/services/AppConfigService.java
index a31b0b8..df3e5b6 100644
--- a/server.services/src/main/java/cl/jonnattan/emulator/services/AppConfigService.java
+++ b/server.services/src/main/java/cl/jonnattan/emulator/services/AppConfigService.java
@@ -4,7 +4,6 @@
import cl.jonnattan.emulator.dto.AppListConfigurationDTOResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -22,8 +21,11 @@ public class AppConfigService implements IConfigurations {
private static final Logger logger = LoggerFactory.getLogger(AppConfigService.class);
- @Autowired
- private IDaoConfiguration configRepository;
+ private final IDaoConfiguration configRepository;
+
+ public AppConfigService(IDaoConfiguration configRepository) {
+ this.configRepository = configRepository;
+ }
@Override
@Transactional
@@ -32,26 +34,29 @@ public String updateConfigurations(AppConfigurationRequestDTO request) throws Co
String response = "Se actualiza configuración";
try {
Configuration conf = configRepository.findByEndpoint(request.getEndPoint());
- if (conf != null) {
- if (request.getError().booleanValue()) {
- conf.setCode(request.getCode());
- conf.setMessage(request.getMessage());
- conf.setType(TypeResponse.getType(request.getType()));
- conf.setError(request.getError());
- } else {
- conf.setCode(null);
- conf.setMessage(null);
- conf.setType(TypeResponse.HTTP_RESPONSE_200);
- conf.setError(false);
- }
- logger.info("************** UPDATE CONFIGURACION **************** ");
- logger.info("Se reporta Código error: {}", conf.getCode());
- logger.info("Se reporta Mensaje error: {}", conf.getMessage());
- logger.info("Se reporta Tipo error: {}", conf.getType());
- logger.info("************************************************* ");
- configRepository.save(conf);
- } else
+ if (conf == null) {
createConfigurations(request);
+ return response;
+ }
+ if (request.getError().booleanValue()) {
+ conf.setCode(request.getCode());
+ conf.setMessage(request.getMessage());
+ conf.setType(TypeResponse.getType(request.getType()));
+ conf.setError(request.getError());
+ } else {
+ conf.setCode(null);
+ conf.setMessage(null);
+ conf.setType(TypeResponse.HTTP_RESPONSE_200);
+ conf.setError(false);
+ }
+ logger.info("************** UPDATE CONFIGURACION **************** ");
+ logger.info("Se reporta Código error: {}", conf.getCode());
+ logger.info("Se reporta Mensaje error: {}", conf.getMessage());
+ logger.info("Se reporta Tipo error: {}", conf.getType());
+ logger.info("************************************************* ");
+ configRepository.save(conf);
+ } catch (ConfException e) {
+ throw e;
} catch (Exception e) {
throw new ConfException("[" + e.getMessage() + "] Actualizando Configuración");
}
@@ -100,38 +105,41 @@ public String saveConfigurations(AppConfigurationRequestDTO request) throws Conf
Configuration conf = configRepository.findByEndpoint(request.getEndPoint());
if (conf != null) {
response = updateConfigurations(request);
- } else
+ } else {
response = createConfigurations(request);
+ }
+ } catch (ConfException e) {
+ throw e;
} catch (Exception e) {
throw new ConfException(e.getMessage());
}
return response;
}
- @Override
- @Transactional(readOnly = true)
- public AppListConfigurationDTOResponse getConfigurations() throws ConfException {
- logger.info("Service para listar las configuraciones");
- AppListConfigurationDTOResponse configurations = new AppListConfigurationDTOResponse();
- List list = configurations.getConfigurations();
- try {
- Iterable confs = configRepository.findAll();
- for(Configuration c : confs) {
- AppConfigurationResponseDTO config = new AppConfigurationResponseDTO();
- config.setType( c.getType().getValue() );
- config.setCode( c.getCode() );
- config.setMessage( c.getMessage() );
- config.setError( c.getError() );
- config.setEndPoint( c.getEndpoint() );
- config.setLastUpdate( c.getUpdatedAt() );
- list.add( config );
- }
- configurations.setConfigurations( list );
- } catch (Exception e) {
- throw new ConfException(e.getMessage());
- }
- return configurations;
- }
+ @Override
+ @Transactional(readOnly = true)
+ public AppListConfigurationDTOResponse getConfigurations() throws ConfException {
+ logger.info("Service para listar las configuraciones");
+ AppListConfigurationDTOResponse configurations = new AppListConfigurationDTOResponse();
+ List list = configurations.getConfigurations();
+ try {
+ Iterable confs = configRepository.findAll();
+ for(Configuration c : confs) {
+ AppConfigurationResponseDTO config = new AppConfigurationResponseDTO();
+ config.setType( c.getType().getValue() );
+ config.setCode( c.getCode() );
+ config.setMessage( c.getMessage() );
+ config.setError( c.getError() );
+ config.setEndPoint( c.getEndpoint() );
+ config.setLastUpdate( c.getUpdatedAt() );
+ list.add( config );
+ }
+ configurations.setConfigurations( list );
+ } catch (Exception e) {
+ throw new ConfException(e.getMessage());
+ }
+ return configurations;
+ }
@SuppressWarnings("null")
@Override
diff --git a/server.services/src/main/java/cl/jonnattan/emulator/services/CardService.java b/server.services/src/main/java/cl/jonnattan/emulator/services/CardService.java
index 91b8bbb..d5cd803 100644
--- a/server.services/src/main/java/cl/jonnattan/emulator/services/CardService.java
+++ b/server.services/src/main/java/cl/jonnattan/emulator/services/CardService.java
@@ -8,7 +8,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -39,14 +38,15 @@ public class CardService implements ICard {
private static final Logger logger = LoggerFactory.getLogger(CardService.class);
- @Autowired
- private IDaoCard cardRepository;
+ private final IDaoCard cardRepository;
+ private final IDaoDevice deviceRepository;
+ private final IUtilities util;
- @Autowired
- private IDaoDevice deviceRepository;
-
- @Autowired
- private IUtilities util;
+ public CardService(IDaoCard cardRepository, IDaoDevice deviceRepository, IUtilities util) {
+ this.cardRepository = cardRepository;
+ this.deviceRepository = deviceRepository;
+ this.util = util;
+ }
@Override
@Transactional
@@ -72,7 +72,7 @@ public EdrTokenGetDigitalPanResponseDTO cardSearch(EdrTokenGetDigitalPanRequestD
Long rId = Long.parseLong(request.getRequestorInfo().getRid());
String dataCard = request.getCardInfo().getData().getProfile();
- String cardNumber = "**** **** **** ****";
+ String cardNumber = UtilConst.MASKED_CARD;
// Card Info es un json que trae el numero de tarjeta...
String msg = util.decryptRSA(dataCard);
@@ -81,8 +81,9 @@ public EdrTokenGetDigitalPanResponseDTO cardSearch(EdrTokenGetDigitalPanRequestD
String tokenCard = util.getTokenCard(clientId);
if (map != null) {
cardNumber = (String) map.get("fpan");
- if (cardNumber != null)
+ if (cardNumber != null) {
tokenCard = util.getTokenCard(cardNumber);
+ }
}
// busca la tarjeta inscrita
Card card = cardRepository.findByCardNumber(cardNumber);
@@ -129,8 +130,9 @@ public IEmulator processTNP(HttpServletRequest request, HttpHeaders headerRx) th
if (dataInUrl.indexOf("actions") > 0) {
action = EActions.getAction(dataInUrl);
- if (!action.equals(EActions.NONE))
+ if (!action.equals(EActions.NONE)) {
dataInUrl = dataInUrl.replace(action.getEnd(), "");
+ }
dataInUrl = dataInUrl.trim();
}
@@ -142,8 +144,9 @@ public IEmulator processTNP(HttpServletRequest request, HttpHeaders headerRx) th
int dato = -1;
ServletInputStream sis = request.getInputStream();
ByteBuffer bb = ByteBuffer.allocate(1024);
- while ((dato = sis.read()) != -1)
+ while ((dato = sis.read()) != -1) {
bb.put((byte) dato);
+ }
bb.flip();
int len = bb.remaining();
String body = "";
@@ -219,7 +222,7 @@ private ActivatePaymentMethodResponseDTO processAssignPinTNP(Card card, String b
/**
* Procesa busqueda de tarjetas TNP
- *
+ *
* @param tokenCipher
* @param card
* @return
@@ -239,7 +242,7 @@ private GetPaymentMethodInfoResponseDTO processSearchTNP(final String tokenCiphe
response.setData(data);
String[] strs = { "EMULATOR", "EDG", "SERVICES" };
- meta.setStatus("ACTIVE");
+ meta.setStatus(UtilConst.STATUS_ACTIVE);
meta.setMessages(strs);
response.setMeta(meta);
return response;
@@ -262,25 +265,27 @@ public EdrTokenGetTokenResponseDTO getToken(String token, HttpHeaders headerRx)
// el token es del device
Device device = deviceRepository.findByToken(token);
- if (device != null) {
- logger.info("Dispositivo encontrado encontrado: {} ", token);
- EdrTokenGetTokenResponseDTO.TokenInfo tokeninfo = new EdrTokenGetTokenResponseDTO.TokenInfo();
- EdrTokenGetTokenResponseDTO.Profile profile = new EdrTokenGetTokenResponseDTO.Profile();
- // con el card asociado al enrolamiento
- Card card = cardRepository.findByToken(device.getCard());
- if (card != null) {
- String toCipher = "{\"dpan\":\"" + card.getCardNumber() + "\",\"cvv\":\"123\",\"dexp\":\"12/21\"}";
- logger.info("DATA: {}", toCipher);
- profile.setProfile(util.encryptRSA(toCipher));
- tokeninfo.setData(profile);
- tokeninfo.setReference(device.getToken());
- tokeninfo.setStatus("ACTIVE");
- response.setTokeninfo(tokeninfo);
- } else
- throw new EmulatorException("No existe tarjeta para token", "5001");
- } else
+ if (device == null) {
throw new EmulatorException("No existe tarjeta para token", "5001");
-
+ }
+ logger.info("Dispositivo encontrado encontrado: {} ", token);
+ EdrTokenGetTokenResponseDTO.TokenInfo tokeninfo = new EdrTokenGetTokenResponseDTO.TokenInfo();
+ EdrTokenGetTokenResponseDTO.Profile profile = new EdrTokenGetTokenResponseDTO.Profile();
+ // con el card asociado al enrolamiento
+ Card card = cardRepository.findByToken(device.getCard());
+ if (card == null) {
+ throw new EmulatorException("No existe tarjeta para token", "5001");
+ }
+ String toCipher = "{\"dpan\":\"" + card.getCardNumber() + "\",\"cvv\":\"123\",\"dexp\":\"12/21\"}";
+ logger.info("DATA: {}", toCipher);
+ profile.setProfile(util.encryptRSA(toCipher));
+ tokeninfo.setData(profile);
+ tokeninfo.setReference(device.getToken());
+ tokeninfo.setStatus(UtilConst.STATUS_ACTIVE);
+ response.setTokeninfo(tokeninfo);
+
+ } catch (EmulatorException e) {
+ throw e;
} catch (Exception e) {
logger.error("Error: ", e);
throw new EmulatorException(e.getMessage() != null ? e.getMessage() : "Error desconocido");
@@ -312,7 +317,7 @@ public EdrTokenEnrollResponseDTO enrollDevice(EdrTokenEnrollmentRequestDTO reque
String dataCard = request.getCardInfo().getData().getProfile();
- String cardNumber = "**** **** **** ****";
+ String cardNumber = UtilConst.MASKED_CARD;
String msg = util.decryptRSA(dataCard);
logger.info("CardInfo: {}", msg);
@@ -321,62 +326,63 @@ public EdrTokenEnrollResponseDTO enrollDevice(EdrTokenEnrollmentRequestDTO reque
String tokenCard = util.getTokenCard(clientId);
if (map != null) {
cardNumber = (String) map.get("fpan");
- if (cardNumber != null)
+ if (cardNumber != null) {
tokenCard = util.getTokenCard(cardNumber);
+ }
}
logger.info("CARD: {} TOKEN: {}", cardNumber, tokenCard);
- if (cardNumber.equals("**** **** **** ****")) {
+ if (cardNumber.equals(UtilConst.MASKED_CARD)) {
throw new EmulatorException("Tarjeta no existe, el metodo search dijo puras mentiras", "5000");
- } else {
- Card card = cardRepository.findByCardNumber(cardNumber);
- if (card != null) {
- logger.info("Los token de tarjetas son: {}",
- (tokenCard.equals(card.getToken()) ? "IGUALES" : "DISTINTOS"));
- if (card.getToken().equals(tokenCard)) {
- Device device = deviceRepository.findByCard(card.getToken());
- if (device != null) {
- logger.info("Dispositivo ya existe, el token es: {}", device.getToken());
- EdrTokenEnrollResponseDTO.TokenInfo tokenInfo = new EdrTokenEnrollResponseDTO.TokenInfo();
- tokenInfo.setHref("EMULATOR-REF");
- tokenInfo.setReference(device.getToken());
- tokenInfo.setReason("REASON-EMULATOR ");
- tokenInfo.setStatus("ACTIVE");
- response.setTokenInfo(tokenInfo);
-
- CardInfo cardInfo = new CardInfo();
- cardInfo.setReference(device.getToken());
- response.setCardInfo(cardInfo);
- response.setReference(card.getToken());
-
- } else {
- String tokenDevice = util.SHA256(body);
- logger.info("Dispositivo nuevo, el token es: {}", tokenDevice);
-
- device = new Device();
- device.setRequest(body);
-
- device.setToken(tokenDevice);
- device.setCard(card.getToken());
- deviceRepository.save(device);
-
- EdrTokenEnrollResponseDTO.TokenInfo tokenInfo = new EdrTokenEnrollResponseDTO.TokenInfo();
- tokenInfo.setHref("EMULATOR-REF");
- tokenInfo.setReference(tokenDevice);
- tokenInfo.setReason("REASON-EMULATOR ");
- tokenInfo.setStatus("ACTIVE");
- response.setTokenInfo(tokenInfo);
-
- CardInfo cardInfo = new CardInfo();
- cardInfo.setReference(card.getToken());
- response.setCardInfo(cardInfo);
- response.setReference(card.getToken());
- }
+ }
+ Card card = cardRepository.findByCardNumber(cardNumber);
+ if (card != null) {
+ logger.info("Los token de tarjetas son: {}",
+ (tokenCard.equals(card.getToken()) ? "IGUALES" : "DISTINTOS"));
+ if (card.getToken().equals(tokenCard)) {
+ Device device = deviceRepository.findByCard(card.getToken());
+ if (device != null) {
+ logger.info("Dispositivo ya existe, el token es: {}", device.getToken());
+ EdrTokenEnrollResponseDTO.TokenInfo tokenInfo = new EdrTokenEnrollResponseDTO.TokenInfo();
+ tokenInfo.setHref(UtilConst.REF_EMULATOR);
+ tokenInfo.setReference(device.getToken());
+ tokenInfo.setReason(UtilConst.REASON_EMULATOR);
+ tokenInfo.setStatus(UtilConst.STATUS_ACTIVE);
+ response.setTokenInfo(tokenInfo);
+
+ CardInfo cardInfo = new CardInfo();
+ cardInfo.setReference(device.getToken());
+ response.setCardInfo(cardInfo);
+ response.setReference(card.getToken());
+
+ } else {
+ String tokenDevice = util.SHA256(body);
+ logger.info("Dispositivo nuevo, el token es: {}", tokenDevice);
+
+ device = new Device();
+ device.setRequest(body);
+
+ device.setToken(tokenDevice);
+ device.setCard(card.getToken());
+ deviceRepository.save(device);
+
+ EdrTokenEnrollResponseDTO.TokenInfo tokenInfo = new EdrTokenEnrollResponseDTO.TokenInfo();
+ tokenInfo.setHref(UtilConst.REF_EMULATOR);
+ tokenInfo.setReference(tokenDevice);
+ tokenInfo.setReason(UtilConst.REASON_EMULATOR);
+ tokenInfo.setStatus(UtilConst.STATUS_ACTIVE);
+ response.setTokenInfo(tokenInfo);
+
+ CardInfo cardInfo = new CardInfo();
+ cardInfo.setReference(card.getToken());
+ response.setCardInfo(cardInfo);
+ response.setReference(card.getToken());
}
}
-
}
+ } catch (EmulatorException e) {
+ throw e;
} catch (Exception e) {
logger.error("Error: ", e);
throw new EmulatorException(e.getMessage());
diff --git a/server.services/src/main/java/cl/jonnattan/emulator/services/CxpService.java b/server.services/src/main/java/cl/jonnattan/emulator/services/CxpService.java
index 0e3d464..eb1038e 100644
--- a/server.services/src/main/java/cl/jonnattan/emulator/services/CxpService.java
+++ b/server.services/src/main/java/cl/jonnattan/emulator/services/CxpService.java
@@ -6,7 +6,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
@@ -33,11 +32,8 @@ private enum Enviroments {
STAGING, DEVELOP, PRODUCTION
}
- @Autowired
- private RestTemplate restTemplateWithTimeout;
-
- @Autowired
- private IUtilities util;
+ private final RestTemplate restTemplateWithTimeout;
+ private final IUtilities util;
@Value("${cxp.urls}")
private String address;
@@ -60,6 +56,11 @@ private enum Enviroments {
private Enviroments enviroment = Enviroments.DEVELOP;
+ public CxpService(RestTemplate restTemplateWithTimeout, IUtilities util) {
+ this.restTemplateWithTimeout = restTemplateWithTimeout;
+ this.util = util;
+ }
+
@PostConstruct
public void init() {
enviroment = Enviroments.values()[index - 1];
@@ -119,8 +120,9 @@ public ICxpResponse processPostRequest(HttpServletRequest request, HttpHeaders h
String msg = String.format("Enviroment %s - Use ApiKey[%s]",enviroment, newKey);
logger.info("{}", msg);
StringBuilder text = new StringBuilder("keys: ");
- for (String skey : geokeys)
+ for (String skey : geokeys) {
text.append(String.format("%s ",skey));
+ }
logger.info("{}", text);
msg = String.format("Endpoint Proxy: %s",url);
@@ -137,7 +139,7 @@ public ICxpResponse processPostRequest(HttpServletRequest request, HttpHeaders h
response = res.getBody();
} catch (Exception e) {
- e.printStackTrace();
+ logger.error("Error de comunicacion", e);
throw new EmulatorException("Error de comunicacion");
}
@@ -146,7 +148,7 @@ public ICxpResponse processPostRequest(HttpServletRequest request, HttpHeaders h
/**
* Imprime en pantalla
- *
+ *
* @param request
* @param header
* @throws IOException
@@ -157,8 +159,9 @@ private String printHeaderAndPayload(final HttpServletRequest request, final Htt
int dato = -1;
ServletInputStream sis = request.getInputStream();
ByteBuffer bb = ByteBuffer.allocate(4096);
- while ((dato = sis.read()) != -1)
+ while ((dato = sis.read()) != -1) {
bb.put((byte) dato);
+ }
bb.flip();
int len = bb.remaining();
String body = "";
@@ -188,23 +191,18 @@ public String processGetRequest(HttpServletRequest request, HttpHeaders header)
String response = "";
String uri = request.getRequestURI();
- try {
-
- if (uri.contains("/dev") || uri.contains("/develop")) {
- response = String.format("Enviroment change from %s to Develop",enviroment.name());
- enviroment = Enviroments.DEVELOP;
- } else if (uri.contains("/qa") || uri.contains("/quality") || uri.contains("/staging")) {
- response = String.format("Enviroment change from %s to Staging",enviroment.name());
- enviroment = Enviroments.STAGING;
- } else if (uri.contains("/prod") && uri.contains("/production")) {
- response = String.format("Enviroment change from %s to Production",enviroment.name());
- enviroment = Enviroments.PRODUCTION;
- } else {
- response = String.format("Enviroment not change. Actually is %s",enviroment.name());
- throw new EmulatorException(response);
- }
- } catch (Exception e) {
- e.printStackTrace();
+ if (uri.contains("/dev") || uri.contains("/develop")) {
+ response = String.format("Enviroment change from %s to Develop",enviroment.name());
+ enviroment = Enviroments.DEVELOP;
+ } else if (uri.contains("/qa") || uri.contains("/quality") || uri.contains("/staging")) {
+ response = String.format("Enviroment change from %s to Staging",enviroment.name());
+ enviroment = Enviroments.STAGING;
+ } else if (uri.contains("/prod") && uri.contains("/production")) {
+ response = String.format("Enviroment change from %s to Production",enviroment.name());
+ enviroment = Enviroments.PRODUCTION;
+ } else {
+ response = String.format("Enviroment not change. Actually is %s",enviroment.name());
+ throw new EmulatorException(response);
}
logger.info("Response: {}", response);
return response;
diff --git a/server.services/src/main/java/cl/jonnattan/emulator/services/EdrService.java b/server.services/src/main/java/cl/jonnattan/emulator/services/EdrService.java
index 2155170..d1876bc 100644
--- a/server.services/src/main/java/cl/jonnattan/emulator/services/EdrService.java
+++ b/server.services/src/main/java/cl/jonnattan/emulator/services/EdrService.java
@@ -2,7 +2,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
@@ -25,17 +24,18 @@ public class EdrService implements IEdr {
private static final Logger logger = LoggerFactory.getLogger(EdrService.class);
- @Autowired
- private ObjectMapper objectMapper;
-
- @Autowired
- private IDaoUser userRepository;
-
- @Autowired
- private IUtilities util;
-
- @Autowired
- private RestTemplate restTemplateWithTimeout;
+ private final ObjectMapper objectMapper;
+ private final IDaoUser userRepository;
+ private final IUtilities util;
+ private final RestTemplate restTemplateWithTimeout;
+
+ public EdrService(ObjectMapper objectMapper, IDaoUser userRepository, IUtilities util,
+ RestTemplate restTemplateWithTimeout) {
+ this.objectMapper = objectMapper;
+ this.userRepository = userRepository;
+ this.util = util;
+ this.restTemplateWithTimeout = restTemplateWithTimeout;
+ }
@Transactional
@Override
@@ -57,8 +57,9 @@ public String loginEdenred(MultiValueMap headerRx) throws Emulat
String textRealLogin = realLogin(name, pass, realm);
- if (textRealLogin != null)
+ if (textRealLogin != null) {
accesstoken = textRealLogin;
+ }
User user = userRepository.findByNameUserAndPassword(name, pass);
if (user != null) {
user.setAccessToken(accesstoken);
@@ -89,7 +90,7 @@ public String loginEdenred(MultiValueMap headerRx) throws Emulat
/**
* Realiza el login en la pagina
- *
+ *
* @param name
* @param pass
* @param realm
@@ -107,8 +108,9 @@ private String realLogin(final String name, final String pass, final String real
httpHeaders.set("realm", realm);
// ticket x defecto
String url = "https://certificacion.edenred.cl/EdenredPrivateWebPortal/sitefinity/Authenticate/SWT";
- if (realm.contains("EdenredJunaebWebPortal"))
+ if (realm.contains("EdenredJunaebWebPortal")) {
url = "https://certificacion.edenred.cl/EdenredJunaebWebPortal/Sitefinity/Authenticate/SWT";
+ }
HttpEntity> request = new HttpEntity<>(httpHeaders);
logger.info("endpoint: {} ", url);
@@ -117,8 +119,9 @@ private String realLogin(final String name, final String pass, final String real
logger.info("Response: {}", msg);
body = response.getBody();
- if (body == null || !body.contains("wrap_access_token"))
+ if (body == null || !body.contains("wrap_access_token")) {
body = null;
+ }
} catch (NumberFormatException e) {
logger.error("Error", e);
diff --git a/server.services/src/main/java/cl/jonnattan/emulator/services/PageService.java b/server.services/src/main/java/cl/jonnattan/emulator/services/PageService.java
index e546fab..8161543 100644
--- a/server.services/src/main/java/cl/jonnattan/emulator/services/PageService.java
+++ b/server.services/src/main/java/cl/jonnattan/emulator/services/PageService.java
@@ -5,7 +5,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -29,11 +28,13 @@ public class PageService implements IPage {
private static final Logger logger = LoggerFactory.getLogger(PageService.class);
- @Autowired
- private IDaoUser userRepository;
+ private final IDaoUser userRepository;
+ private final IUtilities util;
- @Autowired
- private IUtilities util;
+ public PageService(IDaoUser userRepository, IUtilities util) {
+ this.userRepository = userRepository;
+ this.util = util;
+ }
@Override
public IEmulator getUsers(final HttpHeaders header) throws EmulatorException {
@@ -42,8 +43,9 @@ public IEmulator getUsers(final HttpHeaders header) throws EmulatorException {
Iterable users = userRepository.findAll();
response = new UserListDTOResponse();
List list = ((UserListDTOResponse) response).getUsers();
- for (User user : users)
+ for (User user : users) {
list.add(entityToDto(user));
+ }
} catch (Exception e) {
throw new EmulatorException("Error obteniendo usuario", "6500");
}
@@ -52,7 +54,7 @@ public IEmulator getUsers(final HttpHeaders header) throws EmulatorException {
/**
* Convierte el Entity en un DTO
- *
+ *
* @param user
* @return
*/
@@ -95,8 +97,9 @@ public IEmulator save(final MultiValueMap params, final HttpHead
User entity = null;
- if (dto.getNameUser() == null || dto.getNameUser().isEmpty())
+ if (dto.getNameUser() == null || dto.getNameUser().isEmpty()) {
throw new EmulatorException("Campo Mail es Obligacion", "6500");
+ }
entity = userRepository.findByRut(dto.getRut());
entity = entity == null ? userRepository.findByMail(dto.getMail()) : entity;
@@ -124,8 +127,10 @@ public IEmulator save(final MultiValueMap params, final HttpHead
User userbd = userRepository.save(entity);
response = new UserSaveResponse();
((UserSaveResponse) response).setId(userbd.getId());
+ } catch (EmulatorException e) {
+ throw e;
} catch (Exception e) {
- e.printStackTrace();
+ logger.error("Error guardando usuario", e);
throw new EmulatorException("Error guardando usuario", "6500");
}
return response;
diff --git a/server.services/src/main/java/cl/jonnattan/emulator/services/PrmService.java b/server.services/src/main/java/cl/jonnattan/emulator/services/PrmService.java
index deaa50f..b6eb386 100644
--- a/server.services/src/main/java/cl/jonnattan/emulator/services/PrmService.java
+++ b/server.services/src/main/java/cl/jonnattan/emulator/services/PrmService.java
@@ -4,7 +4,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
@@ -21,8 +20,11 @@ public class PrmService implements IPrm {
private static final Logger logger = LoggerFactory.getLogger(PrmService.class);
- @Autowired
- ObjectMapper objectMapper;
+ private final ObjectMapper objectMapper;
+
+ public PrmService(ObjectMapper objectMapper) {
+ this.objectMapper = objectMapper;
+ }
@Override
public EdrPaymentLogonResponseDTO logon(String requestor, HttpHeaders headerRx, EdrPaymentLogonRequestDTO request)
diff --git a/server.services/src/main/java/cl/jonnattan/emulator/services/TransactionService.java b/server.services/src/main/java/cl/jonnattan/emulator/services/TransactionService.java
index 6c002c0..6ea4cff 100644
--- a/server.services/src/main/java/cl/jonnattan/emulator/services/TransactionService.java
+++ b/server.services/src/main/java/cl/jonnattan/emulator/services/TransactionService.java
@@ -5,7 +5,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -33,15 +32,18 @@ public class TransactionService implements ITransactions {
private static final Logger logger = LoggerFactory.getLogger(TransactionService.class);
- @Autowired
- private IDaoTransaction transactionRepository;
- @Autowired
- private IDaoCard cardRepository;
- @Autowired
- private IDaoDevice deviceRepository;
-
- @Autowired
- private IUtilities util;
+ private final IDaoTransaction transactionRepository;
+ private final IDaoCard cardRepository;
+ private final IDaoDevice deviceRepository;
+ private final IUtilities util;
+
+ public TransactionService(IDaoTransaction transactionRepository, IDaoCard cardRepository,
+ IDaoDevice deviceRepository, IUtilities util) {
+ this.transactionRepository = transactionRepository;
+ this.cardRepository = cardRepository;
+ this.deviceRepository = deviceRepository;
+ this.util = util;
+ }
@Override
@Transactional
@@ -70,10 +72,12 @@ public EdrPaymentAuthorizeResponseDTO createTransaction(EdrPayAuthorizeRequestDT
if (device != null) {
logger.info("Card: {}", device.getCard());
Card card = cardRepository.findByToken(device.getCard());
- if (card != null)
+ if (card != null) {
cardNumber = card.getCardNumber();
- } else
+ }
+ } else {
logger.info("####### dispositivo no encontrado");
+ }
}
}
String msg = util.decryptRSA(dataCard);
@@ -107,9 +111,9 @@ public EdrPaymentAuthorizeResponseDTO createTransaction(EdrPayAuthorizeRequestDT
response.setTransaction(request.getTransaction());
// Esto es lo que importa para IONIX
EdrPaymentAuthorizeResponseDTO.Transactionex trans = new EdrPaymentAuthorizeResponseDTO.Transactionex();
- trans.setStatus("APPROVED");
- trans.setAvailablebalance("1005260.0");
- trans.setResponsecode("200");
+ trans.setStatus(UtilConst.STATUS_APPROVED);
+ trans.setAvailablebalance(UtilConst.DEFAULT_BALANCE);
+ trans.setResponsecode(UtilConst.RESPONSE_CODE_200);
trans.setAuthnumber(authId);
response.setTransactionex(trans);
@@ -140,33 +144,35 @@ public EdrPaymentReverseResponseDTO reverseTransaction(EdrPaymentReverseRequestD
String idTransaction = request.getTransactionVoid().getAuthorization().getId();
Transaction transaction = transactionRepository.findByAuthorizationId(idTransaction);
- if (transaction != null) {
- if (transaction.getStatus().equals(TransactionStatus.AUTHORIZED)) {
- transactionRepository.saveStatusById(TransactionStatus.REVERSED, transaction.getId(), new Date());
- response.setRequestorInfo(request.getRequestorInfo());
- response.setTransactionVoid(request.getTransactionVoid());
-
- // Esto es lo que importa para IONIX
- EdrPaymentReverseResponseDTO.Transactionex trans = new EdrPaymentReverseResponseDTO.Transactionex();
- trans.setStatus("APPROVED");
- trans.setAvailablebalance("1005260.0");
- trans.setResponsecode("200");
- trans.setAuthnumber(idTransaction);
- trans.setMcc("EMULATOR-MCC");
- response.setTransactionex(trans);
- // se devuelve la plata a la tarjeta
- Card card = cardRepository.findByCardNumber(transaction.getCard());
- if (card != null) {
- Long value = card.getAmount();
- value += Long.parseLong(transaction.getAmount());
- trans.setAvailablebalance(String.format("%.1f",(double) value));
- cardRepository.saveAmountById(value, card.getId(), new Date());
- }
- } else
- throw new EmulatorException("Transaction invalid status");
- } else
+ if (transaction == null) {
throw new EmulatorException("Transaction not found");
+ }
+ if (!transaction.getStatus().equals(TransactionStatus.AUTHORIZED)) {
+ throw new EmulatorException("Transaction invalid status");
+ }
+ transactionRepository.saveStatusById(TransactionStatus.REVERSED, transaction.getId(), new Date());
+ response.setRequestorInfo(request.getRequestorInfo());
+ response.setTransactionVoid(request.getTransactionVoid());
+
+ // Esto es lo que importa para IONIX
+ EdrPaymentReverseResponseDTO.Transactionex trans = new EdrPaymentReverseResponseDTO.Transactionex();
+ trans.setStatus(UtilConst.STATUS_APPROVED);
+ trans.setAvailablebalance(UtilConst.DEFAULT_BALANCE);
+ trans.setResponsecode(UtilConst.RESPONSE_CODE_200);
+ trans.setAuthnumber(idTransaction);
+ trans.setMcc(UtilConst.EMULATOR_MCC);
+ response.setTransactionex(trans);
+ // se devuelve la plata a la tarjeta
+ Card card = cardRepository.findByCardNumber(transaction.getCard());
+ if (card != null) {
+ Long value = card.getAmount();
+ value += Long.parseLong(transaction.getAmount());
+ trans.setAvailablebalance(String.format("%.1f",(double) value));
+ cardRepository.saveAmountById(value, card.getId(), new Date());
+ }
+ } catch (EmulatorException e) {
+ throw e;
} catch (Exception e) {
logger.error("Error: ", e);
throw new EmulatorException("Error reversando transacción", "32441");
@@ -194,7 +200,7 @@ public EdrPaymentCreateCryptogramResponseDTO createCriptogram(EdrPaymentCreateCr
}
EdrPaymentCreateCryptogramResponseDTO.TokenInfo tokenInfo = new EdrPaymentCreateCryptogramResponseDTO.TokenInfo();
EdrPaymentCreateCryptogramResponseDTO.CripData data = new EdrPaymentCreateCryptogramResponseDTO.CripData();
- data.setAtc("ATC-EMULATOR");
+ data.setAtc(UtilConst.ATC_EMULATOR);
data.setCriptogram(cryptogram);
tokenInfo.setData(data);
tokenInfo.setReference("REF-EMULATOR");
diff --git a/server.services/src/main/java/cl/jonnattan/emulator/services/TrmService.java b/server.services/src/main/java/cl/jonnattan/emulator/services/TrmService.java
index 64d0c8f..e29619b 100644
--- a/server.services/src/main/java/cl/jonnattan/emulator/services/TrmService.java
+++ b/server.services/src/main/java/cl/jonnattan/emulator/services/TrmService.java
@@ -4,7 +4,6 @@
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
@@ -22,8 +21,11 @@ public class TrmService implements ITrm {
private static final Logger logger = LoggerFactory.getLogger(TrmService.class);
- @Autowired
- ObjectMapper objectMapper;
+ private final ObjectMapper objectMapper;
+
+ public TrmService(ObjectMapper objectMapper) {
+ this.objectMapper = objectMapper;
+ }
@Override
public EdrTokenLogonResponseDTO logon(String requetor, HttpHeaders headerRx, EdrTokenLogonRequestDTO request)
@@ -33,12 +35,12 @@ public EdrTokenLogonResponseDTO logon(String requetor, HttpHeaders headerRx, Edr
try {
String body = objectMapper.writeValueAsString(request);
String header = objectMapper.writeValueAsString(headerRx);
-
- List list = headerRx.get("requestid");
+
+ List list = headerRx.get(UtilConst.REQUEST_ID);
String requestId = list != null && !list.isEmpty() ? list.get(0) : UtilConst.NO_INFO;
- list = headerRx.get("client_id");
+ list = headerRx.get(UtilConst.CLIENT_ID);
String clientId = list != null && !list.isEmpty() ? list.get(0) : UtilConst.NO_INFO;
- list = headerRx.get("access_token");
+ list = headerRx.get(UtilConst.ACCESS_TOKEN);
String accessToken = list != null && !list.isEmpty() ? list.get(0) : UtilConst.NO_INFO;
logger.info("requestid : {}", requestId);
@@ -47,7 +49,7 @@ public EdrTokenLogonResponseDTO logon(String requetor, HttpHeaders headerRx, Edr
logger.info("Request Body : {}", body);
logger.info("Request Header: {}", header);
-
+
} catch (JsonProcessingException e) {
logger.error("Error: ", e);
throw new EmulatorException(e.getMessage());
@@ -58,18 +60,18 @@ public EdrTokenLogonResponseDTO logon(String requetor, HttpHeaders headerRx, Edr
private EdrTokenLogonResponseDTO getTest() {
EdrTokenLogonResponseDTO response = new EdrTokenLogonResponseDTO();
-
+
List tsps = new ArrayList<>();
EdrTokenLogonResponseDTO.Tsp tsp = new EdrTokenLogonResponseDTO.Tsp();
tsp.setId("2e936958-9fbf-11e4-89d3-123b93f75cba");
tsp.setPriority(1);
tsps.add(tsp);
-
+
EdrTokenLogonResponseDTO.Enrollment enroll = new EdrTokenLogonResponseDTO.Enrollment();
List list = new ArrayList<>();
list.add("PAN_16");
enroll.setParams( list );
-
+
List bins = new ArrayList<>();
//--------------------------------------
EdrTokenLogonResponseDTO.Bin bin = new EdrTokenLogonResponseDTO.Bin();
diff --git a/server.services/src/main/java/cl/jonnattan/emulator/utils/UtilConst.java b/server.services/src/main/java/cl/jonnattan/emulator/utils/UtilConst.java
index e32c4b8..9eea39c 100644
--- a/server.services/src/main/java/cl/jonnattan/emulator/utils/UtilConst.java
+++ b/server.services/src/main/java/cl/jonnattan/emulator/utils/UtilConst.java
@@ -8,6 +8,7 @@ private UtilConst() {
public static final String CRYPTO_PREF = "CRIPTOGRAM-EMULATOR-";
public static final String DEFAULT_CARD = "XXXXXXXXXXXXXXXX";
+ public static final String MASKED_CARD = "**** **** **** ****";
public static final String NO_INFO = "Sin Información";
public static final String TEXT_TO_ENDPOINT = " para enpoint: ";
public static final String CXP_SUSB_KEY = "ocp-apim-subscription-key";
@@ -17,6 +18,15 @@ private UtilConst() {
public static final String REQUEST_ID = "requestid";
public static final String CLIENT_ID = "client_id";
public static final String ACCESS_TOKEN = "access_token";
-
+
+ public static final String STATUS_APPROVED = "APPROVED";
+ public static final String STATUS_ACTIVE = "ACTIVE";
+ public static final String RESPONSE_CODE_200 = "200";
+ public static final String DEFAULT_BALANCE = "1005260.0";
+ public static final String EMULATOR_MCC = "EMULATOR-MCC";
+ public static final String ATC_EMULATOR = "ATC-EMULATOR";
+ public static final String REF_EMULATOR = "EMULATOR-REF";
+ public static final String REASON_EMULATOR = "REASON-EMULATOR ";
+
public static final String LINE = "---------------------------------------------------------------------------------------";
}
diff --git a/server.services/src/main/java/cl/jonnattan/emulator/utils/Utilities.java b/server.services/src/main/java/cl/jonnattan/emulator/utils/Utilities.java
index 639ede7..4a80887 100644
--- a/server.services/src/main/java/cl/jonnattan/emulator/utils/Utilities.java
+++ b/server.services/src/main/java/cl/jonnattan/emulator/utils/Utilities.java
@@ -4,7 +4,8 @@
import java.util.Map;
import org.bouncycastle.util.encoders.Base64;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -17,17 +18,20 @@
@Component
public class Utilities implements IUtilities {
- @Autowired
- private EncrypterBusinessLogicService rsaCipher;
+ private static final Logger logger = LoggerFactory.getLogger(Utilities.class);
- @Autowired
- private ObjectMapper objectMapper;
+ private final EncrypterBusinessLogicService rsaCipher;
+ private final ObjectMapper objectMapper;
+ private final ICipher aesCipher;
+ private final ISignature signature;
- @Autowired
- private ICipher aesCipher;
-
- @Autowired
- private ISignature signature;
+ public Utilities(EncrypterBusinessLogicService rsaCipher, ObjectMapper objectMapper, ICipher aesCipher,
+ ISignature signature) {
+ this.rsaCipher = rsaCipher;
+ this.objectMapper = objectMapper;
+ this.aesCipher = aesCipher;
+ this.signature = signature;
+ }
@Override
public long cksumSHA256(String data) {
@@ -48,7 +52,7 @@ public String decryptRSA(String data) {
byte[] decryptedData = rsaCipher.decrypt(encryptedData);
result = new String(decryptedData);
} catch (Exception e) {
- e.printStackTrace();
+ logger.error("Error decryptRSA", e);
result = "";
}
}
@@ -66,7 +70,7 @@ public String encryptRSA(String data) {
result = new String(bytes);
} catch (Exception e) {
- e.printStackTrace();
+ logger.error("Error encryptRSA", e);
result = "";
}
}
@@ -79,7 +83,7 @@ public String toJson(Object obj) {
try {
resp = (obj != null) ? objectMapper.writeValueAsString(obj) : "NULL";
} catch (JsonProcessingException e) {
- e.printStackTrace();
+ logger.error("Error toJson", e);
resp = "ERROR Convirtiendo a JSON";
}
return resp;
@@ -92,7 +96,7 @@ public Map toMap(String json) {
try {
map = objectMapper.readValue(json, Map.class);
} catch (IOException | NullPointerException e) {
- e.printStackTrace();
+ logger.error("Error toMap", e);
}
return map;
}
@@ -104,7 +108,7 @@ public String decryptAES(String data) {
try {
result = aesCipher.decrypt(data);
} catch (Exception e) {
- e.printStackTrace();
+ logger.error("Error decryptAES", e);
result = "";
}
}
diff --git a/server.services/src/test/java/cl/jonnattan/emulator/services/AppConfigServiceTest.java b/server.services/src/test/java/cl/jonnattan/emulator/services/AppConfigServiceTest.java
new file mode 100644
index 0000000..a6da960
--- /dev/null
+++ b/server.services/src/test/java/cl/jonnattan/emulator/services/AppConfigServiceTest.java
@@ -0,0 +1,161 @@
+package cl.jonnattan.emulator.services;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import cl.jonnattan.emulator.Configuration;
+import cl.jonnattan.emulator.daos.IDaoConfiguration;
+import cl.jonnattan.emulator.dto.AppConfigurationRequestDTO;
+import cl.jonnattan.emulator.dto.AppListConfigurationDTOResponse;
+import cl.jonnattan.emulator.enums.TypeResponse;
+import cl.jonnattan.emulator.utils.ConfException;
+
+@ExtendWith(MockitoExtension.class)
+class AppConfigServiceTest {
+
+ @Mock
+ private IDaoConfiguration configRepository;
+
+ @InjectMocks
+ private AppConfigService service;
+
+ private AppConfigurationRequestDTO buildRequest(Boolean error) {
+ AppConfigurationRequestDTO dto = new AppConfigurationRequestDTO();
+ dto.setEndPoint("/test/endpoint");
+ dto.setError(error);
+ dto.setCode("500");
+ dto.setMessage("Error simulado");
+ dto.setType(500);
+ return dto;
+ }
+
+ @Test
+ void updateConfigurations_existenteConError_actualizaYGuarda() throws ConfException {
+ Configuration existing = new Configuration();
+ existing.setEndpoint("/test/endpoint");
+ when(configRepository.findByEndpoint("/test/endpoint")).thenReturn(existing);
+
+ String result = service.updateConfigurations(buildRequest(Boolean.TRUE));
+
+ assertEquals("Se actualiza configuración", result);
+ verify(configRepository).save(existing);
+ assertEquals("500", existing.getCode());
+ }
+
+ @Test
+ void updateConfigurations_existenteSinError_limpiaCampos() throws ConfException {
+ Configuration existing = new Configuration();
+ when(configRepository.findByEndpoint(any())).thenReturn(existing);
+
+ service.updateConfigurations(buildRequest(Boolean.FALSE));
+
+ assertEquals(null, existing.getCode());
+ assertEquals(null, existing.getMessage());
+ assertEquals(TypeResponse.HTTP_RESPONSE_200, existing.getType());
+ verify(configRepository).save(existing);
+ }
+
+ @Test
+ void updateConfigurations_noExiste_delegaEnCreate() throws ConfException {
+ when(configRepository.findByEndpoint(any())).thenReturn(null);
+
+ String result = service.updateConfigurations(buildRequest(Boolean.TRUE));
+
+ assertNotNull(result);
+ verify(configRepository).save(any(Configuration.class));
+ }
+
+ @Test
+ void createConfigurations_conError_guardaConfiguracion() throws ConfException {
+ String result = service.createConfigurations(buildRequest(Boolean.TRUE));
+
+ assertEquals("Se crea configuración", result);
+ verify(configRepository).save(any(Configuration.class));
+ }
+
+ @Test
+ void createConfigurations_sinError_guardaConTipoOK() throws ConfException {
+ service.createConfigurations(buildRequest(Boolean.FALSE));
+ verify(configRepository).save(any(Configuration.class));
+ }
+
+ @Test
+ void saveConfigurations_existente_llamaUpdate() throws ConfException {
+ Configuration existing = new Configuration();
+ when(configRepository.findByEndpoint("/test/endpoint")).thenReturn(existing, existing);
+
+ String result = service.saveConfigurations(buildRequest(Boolean.TRUE));
+
+ assertNotNull(result);
+ verify(configRepository).save(any(Configuration.class));
+ }
+
+ @Test
+ void saveConfigurations_noExiste_llamaCreate() throws ConfException {
+ when(configRepository.findByEndpoint(any())).thenReturn(null);
+
+ String result = service.saveConfigurations(buildRequest(Boolean.TRUE));
+
+ assertNotNull(result);
+ verify(configRepository).save(any(Configuration.class));
+ }
+
+ @Test
+ void getConfigurations_retornaListaConElementos() throws ConfException {
+ Configuration c = new Configuration();
+ c.setEndpoint("/e");
+ c.setCode("500");
+ c.setMessage("m");
+ c.setError(Boolean.TRUE);
+ c.setType(TypeResponse.HTTP_RESPONSE_500);
+ when(configRepository.findAll()).thenReturn(Collections.singletonList(c));
+
+ AppListConfigurationDTOResponse result = service.getConfigurations();
+
+ assertNotNull(result);
+ assertEquals(1, result.getConfigurations().size());
+ }
+
+ @Test
+ void evaluateEndpoint_sinConfiguracion_noLanza() throws ConfException {
+ when(configRepository.findByEndpoint(any())).thenReturn(null);
+ service.evaluateEndpoint("/cualquiera");
+ verify(configRepository).findByEndpoint("/cualquiera");
+ }
+
+ @Test
+ void evaluateEndpoint_conError_lanzaConfException() {
+ Configuration c = new Configuration();
+ c.setError(Boolean.TRUE);
+ c.setCode("503");
+ c.setMessage("Servicio caído");
+ c.setType(TypeResponse.HTTP_RESPONSE_503);
+ when(configRepository.findByEndpoint(any())).thenReturn(c);
+
+ ConfException ex = assertThrows(ConfException.class, () -> service.evaluateEndpoint("/e"));
+ assertEquals("503", ex.getCode());
+ }
+
+ @Test
+ void evaluateEndpoint_sinError_noLanza() throws ConfException {
+ Configuration c = new Configuration();
+ c.setError(Boolean.FALSE);
+ when(configRepository.findByEndpoint(any())).thenReturn(c);
+
+ service.evaluateEndpoint("/e");
+ verify(configRepository, never()).save(any());
+ }
+}
diff --git a/server.services/src/test/java/cl/jonnattan/emulator/services/CardServiceTest.java b/server.services/src/test/java/cl/jonnattan/emulator/services/CardServiceTest.java
new file mode 100644
index 0000000..2bde4d0
--- /dev/null
+++ b/server.services/src/test/java/cl/jonnattan/emulator/services/CardServiceTest.java
@@ -0,0 +1,268 @@
+package cl.jonnattan.emulator.services;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.HttpHeaders;
+
+import cl.jonnattan.emulator.Card;
+import cl.jonnattan.emulator.Device;
+import cl.jonnattan.emulator.daos.IDaoCard;
+import cl.jonnattan.emulator.daos.IDaoDevice;
+import cl.jonnattan.emulator.dto.EdrTokenEnrollResponseDTO;
+import cl.jonnattan.emulator.dto.EdrTokenEnrollmentRequestDTO;
+import cl.jonnattan.emulator.dto.EdrTokenGetDigitalPanRequestDTO;
+import cl.jonnattan.emulator.dto.EdrTokenGetDigitalPanResponseDTO;
+import cl.jonnattan.emulator.dto.EdrTokenGetTokenResponseDTO;
+import cl.jonnattan.emulator.dto.ints.IEmulator;
+import cl.jonnattan.emulator.interfaces.IUtilities;
+import cl.jonnattan.emulator.utils.EmulatorException;
+import cl.jonnattan.emulator.utils.UtilConst;
+import jakarta.servlet.ReadListener;
+import jakarta.servlet.ServletInputStream;
+import jakarta.servlet.http.HttpServletRequest;
+
+@ExtendWith(MockitoExtension.class)
+class CardServiceTest {
+
+ @Mock
+ private IDaoCard cardRepository;
+ @Mock
+ private IDaoDevice deviceRepository;
+ @Mock
+ private IUtilities util;
+
+ @InjectMocks
+ private CardService service;
+
+ private EdrTokenGetDigitalPanRequestDTO buildSearchRequest() {
+ EdrTokenGetDigitalPanRequestDTO r = new EdrTokenGetDigitalPanRequestDTO();
+ EdrTokenGetDigitalPanRequestDTO.RequestorInfo ri = new EdrTokenGetDigitalPanRequestDTO.RequestorInfo();
+ ri.setRid("123");
+ r.setRequestorInfo(ri);
+ EdrTokenGetDigitalPanRequestDTO.CardInfo ci = new EdrTokenGetDigitalPanRequestDTO.CardInfo();
+ EdrTokenGetDigitalPanRequestDTO.ProfileData pd = new EdrTokenGetDigitalPanRequestDTO.ProfileData();
+ pd.setProfile("CIPHER-PROFILE");
+ ci.setData(pd);
+ r.setCardInfo(ci);
+ return r;
+ }
+
+ @Test
+ void cardSearch_tarjetaEncontrada_retornaResponse() throws EmulatorException {
+ EdrTokenGetDigitalPanRequestDTO req = buildSearchRequest();
+ Map map = new HashMap<>();
+ map.put("fpan", "4242424242424242");
+
+ when(util.toJson(any())).thenReturn("{}");
+ when(util.decryptRSA(any())).thenReturn("{}");
+ when(util.toMap(any())).thenReturn(map);
+ when(util.getTokenCard(any())).thenReturn("TOKEN-X");
+ Card card = new Card();
+ card.setCardNumber("4242424242424242");
+ card.setToken("TOKEN-X");
+ when(cardRepository.findByCardNumber("4242424242424242")).thenReturn(card);
+
+ EdrTokenGetDigitalPanResponseDTO response = service.cardSearch(req, new HttpHeaders());
+
+ assertNotNull(response);
+ assertNotNull(response.getCardInfo());
+ }
+
+ @Test
+ void cardSearch_tarjetaNoExiste_laRegistraYResponde() throws EmulatorException {
+ EdrTokenGetDigitalPanRequestDTO req = buildSearchRequest();
+ Map map = new HashMap<>();
+ map.put("fpan", "99");
+
+ when(util.toJson(any())).thenReturn("{}");
+ when(util.decryptRSA(any())).thenReturn("{}");
+ when(util.toMap(any())).thenReturn(map);
+ when(util.getTokenCard(any())).thenReturn("TK");
+ when(cardRepository.findByCardNumber(any())).thenReturn(null);
+ when(cardRepository.save(any())).thenAnswer(inv -> {
+ Card c = inv.getArgument(0);
+ c.setId(1L);
+ return c;
+ });
+
+ EdrTokenGetDigitalPanResponseDTO response = service.cardSearch(req, new HttpHeaders());
+
+ assertNotNull(response);
+ }
+
+ @Test
+ void cardSearch_error_lanzaEmulatorException() {
+ EdrTokenGetDigitalPanRequestDTO req = buildSearchRequest();
+ when(util.toJson(any())).thenThrow(new RuntimeException("boom"));
+ assertThrows(EmulatorException.class, () -> service.cardSearch(req, new HttpHeaders()));
+ }
+
+ @Test
+ void getToken_deviceNoExiste_lanzaEmulatorException() {
+ when(deviceRepository.findByToken("X")).thenReturn(null);
+ EmulatorException ex = assertThrows(EmulatorException.class,
+ () -> service.getToken("X", new HttpHeaders()));
+ assertNotNull(ex.getMessage());
+ }
+
+ @Test
+ void getToken_deviceSinCard_lanzaEmulatorException() {
+ Device d = new Device();
+ d.setCard("C1");
+ when(deviceRepository.findByToken("TK")).thenReturn(d);
+ when(cardRepository.findByToken("C1")).thenReturn(null);
+
+ assertThrows(EmulatorException.class, () -> service.getToken("TK", new HttpHeaders()));
+ }
+
+ @Test
+ void getToken_ok_retornaTokenInfo() throws EmulatorException {
+ Device d = new Device();
+ d.setCard("C1");
+ d.setToken("TKN");
+ when(deviceRepository.findByToken("TK")).thenReturn(d);
+ Card c = new Card();
+ c.setCardNumber("4242");
+ when(cardRepository.findByToken("C1")).thenReturn(c);
+ when(util.encryptRSA(any())).thenReturn("CIPHER");
+
+ EdrTokenGetTokenResponseDTO response = service.getToken("TK", new HttpHeaders());
+
+ assertNotNull(response);
+ assertNotNull(response.getTokeninfo());
+ }
+
+ @Test
+ void enrollDevice_cardNoIdentificada_lanzaEmulatorException() {
+ EdrTokenEnrollmentRequestDTO req = buildEnrollRequest();
+
+ when(util.toJson(any())).thenReturn("{}");
+ when(util.decryptRSA(any())).thenReturn("{}");
+ when(util.toMap(any())).thenReturn(new HashMap<>());
+ when(util.getTokenCard(any())).thenReturn("TK");
+
+ EmulatorException ex = assertThrows(EmulatorException.class,
+ () -> service.enrollDevice(req, new HttpHeaders()));
+ assertNotNull(ex.getMessage());
+ }
+
+ @Test
+ void enrollDevice_cardYDeviceExisten_retornaExistente() throws EmulatorException {
+ EdrTokenEnrollmentRequestDTO req = buildEnrollRequest();
+ Map map = new HashMap<>();
+ map.put("fpan", "4242");
+
+ when(util.toJson(any())).thenReturn("{}");
+ when(util.decryptRSA(any())).thenReturn("{}");
+ when(util.toMap(any())).thenReturn(map);
+ when(util.getTokenCard(any())).thenReturn("TK-CARD");
+
+ Card card = new Card();
+ card.setToken("TK-CARD");
+ when(cardRepository.findByCardNumber("4242")).thenReturn(card);
+ Device d = new Device();
+ d.setToken("DEV-TOKEN");
+ when(deviceRepository.findByCard("TK-CARD")).thenReturn(d);
+
+ EdrTokenEnrollResponseDTO response = service.enrollDevice(req, new HttpHeaders());
+
+ assertNotNull(response);
+ assertNotNull(response.getTokenInfo());
+ }
+
+ @Test
+ void enrollDevice_cardExisteSinDevice_creaNuevo() throws EmulatorException {
+ EdrTokenEnrollmentRequestDTO req = buildEnrollRequest();
+ Map map = new HashMap<>();
+ map.put("fpan", "4242");
+
+ when(util.toJson(any())).thenReturn("{}");
+ when(util.decryptRSA(any())).thenReturn("{}");
+ when(util.toMap(any())).thenReturn(map);
+ when(util.getTokenCard(any())).thenReturn("TK-CARD");
+ when(util.SHA256(any())).thenReturn("NEW-DEVICE-TK");
+
+ Card card = new Card();
+ card.setToken("TK-CARD");
+ when(cardRepository.findByCardNumber("4242")).thenReturn(card);
+ when(deviceRepository.findByCard("TK-CARD")).thenReturn(null);
+
+ EdrTokenEnrollResponseDTO response = service.enrollDevice(req, new HttpHeaders());
+
+ assertNotNull(response);
+ }
+
+ @Test
+ void processTNP_tarjetaNueva_guardaYRetorna() throws Exception {
+ HttpServletRequest req = mockTnpRequest("/api/v1/foods/cards/ENCODED");
+ HttpHeaders headers = new HttpHeaders();
+ headers.add("Authorization", "Bearer XYZ");
+ headers.add(UtilConst.X_CLIENT_ID, "client");
+ headers.add(UtilConst.X_CLIENT_SECRET, "secret");
+
+ when(util.toJson(any())).thenReturn("{}");
+ when(util.decryptAES(any())).thenReturn("4242");
+ when(util.SHA256(any())).thenReturn("SHA");
+ when(cardRepository.findByCardNumber("4242")).thenReturn(null);
+ when(cardRepository.save(any())).thenAnswer(inv -> {
+ Card c = inv.getArgument(0);
+ c.setId(10L);
+ return c;
+ });
+
+ IEmulator response = service.processTNP(req, headers);
+
+ assertNotNull(response);
+ }
+
+ private EdrTokenEnrollmentRequestDTO buildEnrollRequest() {
+ EdrTokenEnrollmentRequestDTO r = new EdrTokenEnrollmentRequestDTO();
+ EdrTokenEnrollmentRequestDTO.CardInfo ci = new EdrTokenEnrollmentRequestDTO.CardInfo();
+ EdrTokenEnrollmentRequestDTO.ProfileData pd = new EdrTokenEnrollmentRequestDTO.ProfileData();
+ pd.setProfile("CIPHER");
+ ci.setData(pd);
+ r.setCardInfo(ci);
+ return r;
+ }
+
+ private HttpServletRequest mockTnpRequest(String uri) throws IOException {
+ HttpServletRequest req = org.mockito.Mockito.mock(HttpServletRequest.class);
+ when(req.getRequestURI()).thenReturn(uri);
+ ByteArrayInputStream bais = new ByteArrayInputStream(new byte[0]);
+ when(req.getInputStream()).thenReturn(new ServletInputStream() {
+ @Override
+ public int read() {
+ return bais.read();
+ }
+
+ @Override
+ public boolean isFinished() {
+ return bais.available() == 0;
+ }
+
+ @Override
+ public boolean isReady() {
+ return true;
+ }
+
+ @Override
+ public void setReadListener(ReadListener listener) {
+ // noop
+ }
+ });
+ return req;
+ }
+}
diff --git a/server.services/src/test/java/cl/jonnattan/emulator/services/CxpServiceTest.java b/server.services/src/test/java/cl/jonnattan/emulator/services/CxpServiceTest.java
new file mode 100644
index 0000000..52952e8
--- /dev/null
+++ b/server.services/src/test/java/cl/jonnattan/emulator/services/CxpServiceTest.java
@@ -0,0 +1,156 @@
+package cl.jonnattan.emulator.services;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.util.ReflectionTestUtils;
+import org.springframework.web.client.RestTemplate;
+
+import cl.jonnattan.emulator.dto.cxp.CxpResponseDTO;
+import cl.jonnattan.emulator.dto.cxp.ICxpResponse;
+import cl.jonnattan.emulator.interfaces.IUtilities;
+import cl.jonnattan.emulator.utils.EmulatorException;
+import jakarta.servlet.ReadListener;
+import jakarta.servlet.ServletInputStream;
+import jakarta.servlet.http.HttpServletRequest;
+
+@ExtendWith(MockitoExtension.class)
+class CxpServiceTest {
+
+ @Mock
+ private RestTemplate restTemplateWithTimeout;
+ @Mock
+ private IUtilities util;
+
+ @InjectMocks
+ private CxpService service;
+
+ @BeforeEach
+ void init() {
+ ReflectionTestUtils.setField(service, "address", "http://a,http://b,http://c");
+ ReflectionTestUtils.setField(service, "keysOt", "k1,k2,k3");
+ ReflectionTestUtils.setField(service, "keysGeo", "g1,g2,g3");
+ ReflectionTestUtils.setField(service, "keysCotizacion", "c1,c2,c3");
+ ReflectionTestUtils.setField(service, "index", 2);
+ service.init();
+ }
+
+ @Test
+ void processPostRequest_rating_usaCotKey() throws Exception {
+ HttpServletRequest req = mockRequest("/cxp/rating/api/v1.0/rates/courier");
+ CxpResponseDTO body = new CxpResponseDTO();
+ ResponseEntity rsp = ResponseEntity.ok(body);
+ when(restTemplateWithTimeout.postForEntity(any(String.class), any(HttpEntity.class), eq(CxpResponseDTO.class)))
+ .thenReturn(rsp);
+ when(util.toJson(any())).thenReturn("{}");
+
+ ICxpResponse response = service.processPostRequest(req, new HttpHeaders());
+
+ assertNotNull(response);
+ }
+
+ @Test
+ void processPostRequest_transportOrders_usaOtKey() throws Exception {
+ HttpServletRequest req = mockRequest("/cxp/transport-orders/api/v1.0/transport-orders");
+ CxpResponseDTO body = new CxpResponseDTO();
+ when(restTemplateWithTimeout.postForEntity(any(String.class), any(HttpEntity.class), eq(CxpResponseDTO.class)))
+ .thenReturn(ResponseEntity.ok(body));
+ when(util.toJson(any())).thenReturn("{}");
+
+ ICxpResponse response = service.processPostRequest(req, new HttpHeaders());
+
+ assertNotNull(response);
+ }
+
+ @Test
+ void processPostRequest_errorRest_lanzaEmulatorException() throws Exception {
+ HttpServletRequest req = mockRequest("/cxp/otro");
+ when(util.toJson(any())).thenReturn("{}");
+ when(restTemplateWithTimeout.postForEntity(any(String.class), any(HttpEntity.class), eq(CxpResponseDTO.class)))
+ .thenThrow(new RuntimeException("boom"));
+
+ assertThrows(EmulatorException.class, () -> service.processPostRequest(req, new HttpHeaders()));
+ }
+
+ @Test
+ void processGetRequest_dev_cambiaAmbiente() throws Exception {
+ HttpServletRequest req = Mockito.mock(HttpServletRequest.class);
+ when(req.getRequestURI()).thenReturn("/cxp/dev");
+
+ String response = service.processGetRequest(req, new HttpHeaders());
+
+ assertNotNull(response);
+ }
+
+ @Test
+ void processGetRequest_qa_cambiaAmbiente() throws Exception {
+ HttpServletRequest req = Mockito.mock(HttpServletRequest.class);
+ when(req.getRequestURI()).thenReturn("/cxp/qa");
+
+ String response = service.processGetRequest(req, new HttpHeaders());
+
+ assertNotNull(response);
+ }
+
+ @Test
+ void processGetRequest_prodProduction_cambiaAmbiente() throws Exception {
+ HttpServletRequest req = Mockito.mock(HttpServletRequest.class);
+ when(req.getRequestURI()).thenReturn("/cxp/prod/production");
+
+ String response = service.processGetRequest(req, new HttpHeaders());
+
+ assertNotNull(response);
+ }
+
+ @Test
+ void processGetRequest_uriInvalida_lanzaEmulatorException() {
+ HttpServletRequest req = Mockito.mock(HttpServletRequest.class);
+ when(req.getRequestURI()).thenReturn("/cxp/otro");
+
+ assertThrows(EmulatorException.class, () -> service.processGetRequest(req, new HttpHeaders()));
+ }
+
+ private HttpServletRequest mockRequest(String uri) throws IOException {
+ HttpServletRequest req = Mockito.mock(HttpServletRequest.class);
+ when(req.getRequestURI()).thenReturn(uri);
+ ByteArrayInputStream bais = new ByteArrayInputStream("{\"body\":1}".getBytes());
+ when(req.getInputStream()).thenReturn(new ServletInputStream() {
+ @Override
+ public int read() {
+ return bais.read();
+ }
+
+ @Override
+ public boolean isFinished() {
+ return bais.available() == 0;
+ }
+
+ @Override
+ public boolean isReady() {
+ return true;
+ }
+
+ @Override
+ public void setReadListener(ReadListener listener) {
+ // noop
+ }
+ });
+ return req;
+ }
+}
diff --git a/server.services/src/test/java/cl/jonnattan/emulator/services/EdrServiceTest.java b/server.services/src/test/java/cl/jonnattan/emulator/services/EdrServiceTest.java
new file mode 100644
index 0000000..906e04b
--- /dev/null
+++ b/server.services/src/test/java/cl/jonnattan/emulator/services/EdrServiceTest.java
@@ -0,0 +1,91 @@
+package cl.jonnattan.emulator.services;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
+
+import cl.jonnattan.emulator.User;
+import cl.jonnattan.emulator.daos.IDaoUser;
+import cl.jonnattan.emulator.interfaces.IUtilities;
+import cl.jonnattan.emulator.utils.EmulatorException;
+
+@ExtendWith(MockitoExtension.class)
+class EdrServiceTest {
+
+ @Mock
+ private ObjectMapper objectMapper;
+ @Mock
+ private IDaoUser userRepository;
+ @Mock
+ private IUtilities util;
+ @Mock
+ private RestTemplate restTemplateWithTimeout;
+
+ @InjectMocks
+ private EdrService service;
+
+ private MultiValueMap buildHeaders(String realm) {
+ MultiValueMap h = new LinkedMultiValueMap<>();
+ h.put("wrap_name", Collections.singletonList("john"));
+ h.put("wrap_password", Collections.singletonList("pwd"));
+ h.put("realm", Collections.singletonList(realm));
+ return h;
+ }
+
+ @Test
+ void loginEdenred_usuarioExistente_actualizaToken() throws Exception {
+ when(objectMapper.writeValueAsString(any())).thenReturn("{}");
+ when(util.SHA256(any())).thenReturn("HASH-TOKEN");
+ when(util.toJson(any())).thenReturn("{}");
+ ResponseEntity rsp = ResponseEntity.ok("no_token_here");
+ when(restTemplateWithTimeout.postForEntity(any(String.class), any(HttpEntity.class), eq(String.class)))
+ .thenReturn(rsp);
+
+ User existing = new User();
+ existing.setId(1L);
+ when(userRepository.findByNameUserAndPassword("john", "pwd")).thenReturn(existing);
+
+ String result = service.loginEdenred(buildHeaders("EdenredPrivateWebPortal"));
+
+ assertNotNull(result);
+ }
+
+ @Test
+ void loginEdenred_usuarioNoExiste_creaUsuario() throws Exception {
+ when(objectMapper.writeValueAsString(any())).thenReturn("{}");
+ when(util.SHA256(any())).thenReturn("HASH");
+ when(util.toJson(any())).thenReturn("{}");
+ when(restTemplateWithTimeout.postForEntity(any(String.class), any(HttpEntity.class), eq(String.class)))
+ .thenReturn(ResponseEntity.ok(null));
+ when(userRepository.findByNameUserAndPassword(any(), any())).thenReturn(null);
+
+ String result = service.loginEdenred(buildHeaders("EdenredJunaebWebPortal"));
+
+ assertNotNull(result);
+ }
+
+ @Test
+ void loginEdenred_errorEnProceso_lanzaEmulatorException() throws Exception {
+ when(objectMapper.writeValueAsString(any())).thenThrow(new RuntimeException("boom"));
+ EmulatorException ex = assertThrows(EmulatorException.class,
+ () -> service.loginEdenred(buildHeaders("x")));
+ assertNotNull(ex.getMessage());
+ }
+}
diff --git a/server.services/src/test/java/cl/jonnattan/emulator/services/PageServiceTest.java b/server.services/src/test/java/cl/jonnattan/emulator/services/PageServiceTest.java
new file mode 100644
index 0000000..e1d8637
--- /dev/null
+++ b/server.services/src/test/java/cl/jonnattan/emulator/services/PageServiceTest.java
@@ -0,0 +1,123 @@
+package cl.jonnattan.emulator.services;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.HttpHeaders;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+
+import cl.jonnattan.emulator.User;
+import cl.jonnattan.emulator.daos.IDaoUser;
+import cl.jonnattan.emulator.dto.ints.IEmulator;
+import cl.jonnattan.emulator.dto.user.UserListDTOResponse;
+import cl.jonnattan.emulator.dto.user.UserSaveResponse;
+import cl.jonnattan.emulator.enums.EUserType;
+import cl.jonnattan.emulator.interfaces.IUtilities;
+import cl.jonnattan.emulator.utils.EmulatorException;
+
+@ExtendWith(MockitoExtension.class)
+class PageServiceTest {
+
+ @Mock
+ private IDaoUser userRepository;
+
+ @Mock
+ private IUtilities util;
+
+ @InjectMocks
+ private PageService service;
+
+ private User buildUser() {
+ User u = new User();
+ u.setId(1L);
+ u.setRut("11111111-1");
+ u.setMail("a@b.cl");
+ u.setNameUser("user");
+ u.setFullName("Nombre");
+ u.setAge(30);
+ u.setAddress("Dir");
+ u.setCity("Stgo");
+ u.setMobile("9");
+ u.setType(EUserType.NORMAL);
+ return u;
+ }
+
+ @Test
+ void getUsers_retornaListaMapeada() throws EmulatorException {
+ when(userRepository.findAll()).thenReturn(Arrays.asList(buildUser(), buildUser()));
+
+ IEmulator response = service.getUsers(new HttpHeaders());
+
+ assertInstanceOf(UserListDTOResponse.class, response);
+ assertEquals(2, ((UserListDTOResponse) response).getUsers().size());
+ }
+
+ @Test
+ void getUsers_cuandoFalla_lanzaEmulatorException() {
+ when(userRepository.findAll()).thenThrow(new RuntimeException("boom"));
+ EmulatorException ex = assertThrows(EmulatorException.class, () -> service.getUsers(new HttpHeaders()));
+ assertEquals("6500", ex.getCode());
+ }
+
+ @Test
+ void save_usuarioNuevo_creaYRetornaId() throws EmulatorException {
+ MultiValueMap params = new LinkedMultiValueMap<>();
+ params.put("userName", Collections.singletonList("nuevo"));
+ params.put("rut", Collections.singletonList("22222222-2"));
+ params.put("mail", Collections.singletonList("x@y.cl"));
+ params.put("pass", Collections.singletonList("secret"));
+ params.put("type", Collections.singletonList("Normal"));
+ params.put("age", Collections.singletonList("25"));
+
+ when(userRepository.findByRut(any())).thenReturn(null);
+ when(userRepository.findByMail(any())).thenReturn(null);
+ when(util.SHA256(any())).thenReturn("HASH");
+ User saved = buildUser();
+ saved.setId(999L);
+ when(userRepository.save(any())).thenReturn(saved);
+
+ IEmulator response = service.save(params, new HttpHeaders());
+
+ assertInstanceOf(UserSaveResponse.class, response);
+ assertEquals(999L, ((UserSaveResponse) response).getId());
+ }
+
+ @Test
+ void save_usuarioExiste_actualiza() throws EmulatorException {
+ MultiValueMap params = new LinkedMultiValueMap<>();
+ params.put("userName", Collections.singletonList("existe"));
+ params.put("rut", Collections.singletonList("11111111-1"));
+ params.put("type", Collections.singletonList("Administrador"));
+
+ User u = buildUser();
+ when(userRepository.findByRut(any())).thenReturn(u);
+ when(userRepository.save(any())).thenReturn(u);
+
+ IEmulator response = service.save(params, new HttpHeaders());
+
+ assertNotNull(response);
+ }
+
+ @Test
+ void save_sinNameUser_lanzaEmulatorException() {
+ MultiValueMap params = new LinkedMultiValueMap<>();
+ params.put("rut", Collections.singletonList("X"));
+
+ EmulatorException ex = assertThrows(EmulatorException.class,
+ () -> service.save(params, new HttpHeaders()));
+ assertEquals("6500", ex.getCode());
+ }
+}
diff --git a/server.services/src/test/java/cl/jonnattan/emulator/services/PrmServiceTest.java b/server.services/src/test/java/cl/jonnattan/emulator/services/PrmServiceTest.java
new file mode 100644
index 0000000..d77c814
--- /dev/null
+++ b/server.services/src/test/java/cl/jonnattan/emulator/services/PrmServiceTest.java
@@ -0,0 +1,46 @@
+package cl.jonnattan.emulator.services;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.HttpHeaders;
+
+import cl.jonnattan.emulator.dto.EdrPaymentLogonRequestDTO;
+import cl.jonnattan.emulator.dto.EdrPaymentLogonResponseDTO;
+import cl.jonnattan.emulator.utils.EmulatorException;
+
+@ExtendWith(MockitoExtension.class)
+class PrmServiceTest {
+
+ @Mock
+ private ObjectMapper objectMapper;
+
+ @InjectMocks
+ private PrmService service;
+
+ @Test
+ void logon_ok_retornaResponseDTO() throws Exception {
+ when(objectMapper.writeValueAsString(any())).thenReturn("{}");
+ EdrPaymentLogonResponseDTO response = service.logon("REQ", new HttpHeaders(), new EdrPaymentLogonRequestDTO());
+ assertNotNull(response);
+ }
+
+ @Test
+ void logon_jsonError_lanzaEmulatorException() throws Exception {
+ when(objectMapper.writeValueAsString(any())).thenThrow(new JsonProcessingException("boom") {
+ private static final long serialVersionUID = 1L;
+ });
+ assertThrows(EmulatorException.class,
+ () -> service.logon("REQ", new HttpHeaders(), new EdrPaymentLogonRequestDTO()));
+ }
+}
diff --git a/server.services/src/test/java/cl/jonnattan/emulator/services/TransactionServiceTest.java b/server.services/src/test/java/cl/jonnattan/emulator/services/TransactionServiceTest.java
new file mode 100644
index 0000000..116427a
--- /dev/null
+++ b/server.services/src/test/java/cl/jonnattan/emulator/services/TransactionServiceTest.java
@@ -0,0 +1,209 @@
+package cl.jonnattan.emulator.services;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.HttpHeaders;
+
+import cl.jonnattan.emulator.Card;
+import cl.jonnattan.emulator.Device;
+import cl.jonnattan.emulator.Transaction;
+import cl.jonnattan.emulator.daos.IDaoCard;
+import cl.jonnattan.emulator.daos.IDaoDevice;
+import cl.jonnattan.emulator.daos.IDaoTransaction;
+import cl.jonnattan.emulator.dto.Authorization;
+import cl.jonnattan.emulator.dto.EdrPayAuthorizeRequestDTO;
+import cl.jonnattan.emulator.dto.EdrPaymentAuthorizeResponseDTO;
+import cl.jonnattan.emulator.dto.EdrPaymentCreateCryptogramRequestDTO;
+import cl.jonnattan.emulator.dto.EdrPaymentCreateCryptogramResponseDTO;
+import cl.jonnattan.emulator.dto.EdrPaymentReverseRequestDTO;
+import cl.jonnattan.emulator.dto.EdrPaymentReverseResponseDTO;
+import cl.jonnattan.emulator.dto.TransactionVoid;
+import cl.jonnattan.emulator.enums.TransactionStatus;
+import cl.jonnattan.emulator.interfaces.IUtilities;
+import cl.jonnattan.emulator.utils.EmulatorException;
+import cl.jonnattan.emulator.utils.UtilConst;
+
+@ExtendWith(MockitoExtension.class)
+class TransactionServiceTest {
+
+ @Mock
+ private IDaoTransaction transactionRepository;
+ @Mock
+ private IDaoCard cardRepository;
+ @Mock
+ private IDaoDevice deviceRepository;
+ @Mock
+ private IUtilities util;
+
+ @InjectMocks
+ private TransactionService service;
+
+ private static final ObjectMapper mapper = new ObjectMapper();
+
+ private EdrPayAuthorizeRequestDTO buildAuthRequest() throws Exception {
+ String json = "{\"token\":{\"data\":\"CIPHER-DATA\"},\"transaction\":{\"amount\":\"1000\"}}";
+ return mapper.readValue(json, EdrPayAuthorizeRequestDTO.class);
+ }
+
+ private EdrPaymentReverseRequestDTO buildReverseRequest(String authId) {
+ EdrPaymentReverseRequestDTO req = new EdrPaymentReverseRequestDTO();
+ TransactionVoid tv = new TransactionVoid();
+ Authorization auth = new Authorization();
+ auth.setId(authId);
+ tv.setAuthorization(auth);
+ req.setTransactionVoid(tv);
+ return req;
+ }
+
+ @Test
+ void createTransaction_conDispositivoYTarjeta_responde() throws Exception {
+ EdrPayAuthorizeRequestDTO req = buildAuthRequest();
+ Map map = new HashMap<>();
+ map.put("cryptogram", UtilConst.CRYPTO_PREF + "XYZ");
+
+ when(util.toJson(any())).thenReturn("{}");
+ when(util.decryptRSA("CIPHER-DATA")).thenReturn("{\"cryptogram\":\"CRIPTOGRAM-EMULATOR-XYZ\"}");
+ when(util.toMap(any())).thenReturn(map);
+ when(util.cksumSHA256(any())).thenReturn(12345L);
+ Device device = new Device();
+ device.setCard("TOKEN-CARD");
+ when(deviceRepository.findByCryptogram(any())).thenReturn(device);
+ Card card = new Card();
+ card.setCardNumber("4242424242424242");
+ card.setId(1L);
+ card.setAmount(100000L);
+ when(cardRepository.findByToken("TOKEN-CARD")).thenReturn(card);
+ when(cardRepository.findByCardNumber("4242424242424242")).thenReturn(card);
+
+ EdrPaymentAuthorizeResponseDTO response = service.createTransaction(req, new HttpHeaders());
+
+ assertNotNull(response);
+ assertEquals(UtilConst.STATUS_APPROVED, response.getTransactionex().getStatus());
+ assertEquals(UtilConst.RESPONSE_CODE_200, response.getTransactionex().getResponsecode());
+ }
+
+ @Test
+ void createTransaction_sinDispositivo_usaDefaultCard() throws Exception {
+ EdrPayAuthorizeRequestDTO req = buildAuthRequest();
+ Map map = new HashMap<>();
+ map.put("cryptogram", UtilConst.CRYPTO_PREF + "N/A");
+
+ when(util.toJson(any())).thenReturn("{}");
+ when(util.decryptRSA(any())).thenReturn("{}");
+ when(util.toMap(any())).thenReturn(map);
+ when(util.cksumSHA256(any())).thenReturn(999L);
+ when(deviceRepository.findByCryptogram(any())).thenReturn(null);
+
+ EdrPaymentAuthorizeResponseDTO response = service.createTransaction(req, new HttpHeaders());
+
+ assertNotNull(response);
+ }
+
+ @Test
+ void createTransaction_cuandoFalla_lanzaEmulatorException() throws Exception {
+ EdrPayAuthorizeRequestDTO req = buildAuthRequest();
+ when(util.toJson(any())).thenThrow(new RuntimeException("boom"));
+
+ EmulatorException ex = assertThrows(EmulatorException.class,
+ () -> service.createTransaction(req, new HttpHeaders()));
+ assertEquals("5544", ex.getCode());
+ }
+
+ @Test
+ void reverseTransaction_transaccionAutorizada_devuelveAPROBADO() throws EmulatorException {
+ EdrPaymentReverseRequestDTO req = buildReverseRequest("AUTH-1");
+
+ Transaction tx = new Transaction();
+ tx.setId(1L);
+ tx.setStatus(TransactionStatus.AUTHORIZED);
+ tx.setCard("4242");
+ tx.setAmount("500");
+
+ Card card = new Card();
+ card.setId(1L);
+ card.setAmount(1000L);
+
+ when(util.toJson(any())).thenReturn("{}");
+ when(transactionRepository.findByAuthorizationId("AUTH-1")).thenReturn(tx);
+ when(cardRepository.findByCardNumber("4242")).thenReturn(card);
+
+ EdrPaymentReverseResponseDTO response = service.reverseTransaction(req, new HttpHeaders());
+
+ assertEquals(UtilConst.STATUS_APPROVED, response.getTransactionex().getStatus());
+ assertEquals(UtilConst.EMULATOR_MCC, response.getTransactionex().getMcc());
+ }
+
+ @Test
+ void reverseTransaction_transaccionNoExiste_lanzaEmulatorException() {
+ EdrPaymentReverseRequestDTO req = buildReverseRequest("NOEXISTE");
+
+ when(util.toJson(any())).thenReturn("{}");
+ when(transactionRepository.findByAuthorizationId("NOEXISTE")).thenReturn(null);
+
+ assertThrows(EmulatorException.class, () -> service.reverseTransaction(req, new HttpHeaders()));
+ }
+
+ @Test
+ void reverseTransaction_estadoInvalido_lanzaEmulatorException() {
+ EdrPaymentReverseRequestDTO req = buildReverseRequest("X");
+
+ Transaction tx = new Transaction();
+ tx.setStatus(TransactionStatus.REVERSED);
+
+ when(util.toJson(any())).thenReturn("{}");
+ when(transactionRepository.findByAuthorizationId("X")).thenReturn(tx);
+
+ assertThrows(EmulatorException.class, () -> service.reverseTransaction(req, new HttpHeaders()));
+ }
+
+ @Test
+ void createCriptogram_conDevice_retornaCriptograma() throws EmulatorException {
+ EdrPaymentCreateCryptogramRequestDTO req = new EdrPaymentCreateCryptogramRequestDTO();
+ when(util.toJson(any())).thenReturn("{}");
+ when(util.SHA256(any())).thenReturn("HASH");
+ Device device = new Device();
+ device.setId(99L);
+ when(deviceRepository.findByToken("TKN")).thenReturn(device);
+
+ EdrPaymentCreateCryptogramResponseDTO response = service.createCriptogram(req, new HttpHeaders(), "TKN");
+
+ assertNotNull(response);
+ assertEquals(UtilConst.ATC_EMULATOR, response.getTokenInfo().getData().getAtc());
+ }
+
+ @Test
+ void createCriptogram_sinDevice_retornaIgual() throws EmulatorException {
+ EdrPaymentCreateCryptogramRequestDTO req = new EdrPaymentCreateCryptogramRequestDTO();
+ when(util.toJson(any())).thenReturn("{}");
+ when(util.SHA256(any())).thenReturn("HASH");
+ when(deviceRepository.findByToken("TKN")).thenReturn(null);
+
+ EdrPaymentCreateCryptogramResponseDTO response = service.createCriptogram(req, new HttpHeaders(), "TKN");
+
+ assertNotNull(response);
+ }
+
+ @Test
+ void createCriptogram_cuandoFalla_lanzaEmulatorException() {
+ EdrPaymentCreateCryptogramRequestDTO req = new EdrPaymentCreateCryptogramRequestDTO();
+ when(util.toJson(any())).thenThrow(new RuntimeException("boom"));
+
+ EmulatorException ex = assertThrows(EmulatorException.class,
+ () -> service.createCriptogram(req, new HttpHeaders(), "TKN"));
+ assertEquals("5423", ex.getCode());
+ }
+}
diff --git a/server.services/src/test/java/cl/jonnattan/emulator/services/TrmServiceTest.java b/server.services/src/test/java/cl/jonnattan/emulator/services/TrmServiceTest.java
new file mode 100644
index 0000000..64bac9f
--- /dev/null
+++ b/server.services/src/test/java/cl/jonnattan/emulator/services/TrmServiceTest.java
@@ -0,0 +1,46 @@
+package cl.jonnattan.emulator.services;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.HttpHeaders;
+
+import cl.jonnattan.emulator.dto.EdrTokenLogonRequestDTO;
+import cl.jonnattan.emulator.dto.EdrTokenLogonResponseDTO;
+import cl.jonnattan.emulator.utils.EmulatorException;
+
+@ExtendWith(MockitoExtension.class)
+class TrmServiceTest {
+
+ @Mock
+ private ObjectMapper objectMapper;
+
+ @InjectMocks
+ private TrmService service;
+
+ @Test
+ void logon_ok_retornaResponseDTO() throws Exception {
+ when(objectMapper.writeValueAsString(any())).thenReturn("{}");
+ EdrTokenLogonResponseDTO response = service.logon("REQ", new HttpHeaders(), new EdrTokenLogonRequestDTO());
+ assertNotNull(response);
+ }
+
+ @Test
+ void logon_jsonError_lanzaEmulatorException() throws Exception {
+ when(objectMapper.writeValueAsString(any())).thenThrow(new JsonProcessingException("boom") {
+ private static final long serialVersionUID = 1L;
+ });
+ assertThrows(EmulatorException.class,
+ () -> service.logon("REQ", new HttpHeaders(), new EdrTokenLogonRequestDTO()));
+ }
+}
diff --git a/server.services/src/test/java/cl/jonnattan/emulator/utils/ExceptionsTest.java b/server.services/src/test/java/cl/jonnattan/emulator/utils/ExceptionsTest.java
new file mode 100644
index 0000000..9205b94
--- /dev/null
+++ b/server.services/src/test/java/cl/jonnattan/emulator/utils/ExceptionsTest.java
@@ -0,0 +1,63 @@
+package cl.jonnattan.emulator.utils;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.http.HttpStatus;
+
+import cl.jonnattan.emulator.enums.TypeResponse;
+
+class ExceptionsTest {
+
+ @Test
+ void emulatorException_constructorSoloMensaje_codeDefecto() {
+ EmulatorException ex = new EmulatorException("err");
+ assertEquals("err", ex.getMessage());
+ assertEquals("-1", ex.getCode());
+ }
+
+ @Test
+ void emulatorException_constructorConCode() {
+ EmulatorException ex = new EmulatorException("err", "500");
+ assertEquals("500", ex.getCode());
+ }
+
+ @Test
+ void confException_constructorBasico_defaults() {
+ ConfException ex = new ConfException("err");
+ assertEquals("-1", ex.getCode());
+ assertEquals(TypeResponse.HTTP_RESPONSE_200, ex.getType());
+ assertEquals(HttpStatus.OK, ex.getStatus());
+ }
+
+ @Test
+ void confException_setters_actualizanValores() {
+ ConfException ex = new ConfException("err");
+ ex.setCode("42");
+ ex.setType(TypeResponse.HTTP_RESPONSE_500);
+ assertEquals("42", ex.getCode());
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, ex.getStatus());
+ }
+
+ @Test
+ void confException_getStatus_mapeaTodosLosTipos() {
+ assertEquals(HttpStatus.OK, mapStatus(TypeResponse.HTTP_RESPONSE_200));
+ assertEquals(HttpStatus.BAD_REQUEST, mapStatus(TypeResponse.HTTP_RESPONSE_400));
+ assertEquals(HttpStatus.CONFLICT, mapStatus(TypeResponse.HTTP_RESPONSE_409));
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, mapStatus(TypeResponse.HTTP_RESPONSE_500));
+ assertEquals(HttpStatus.SERVICE_UNAVAILABLE, mapStatus(TypeResponse.HTTP_RESPONSE_503));
+ }
+
+ private HttpStatus mapStatus(TypeResponse type) {
+ ConfException ex = new ConfException("m", "c", type);
+ return ex.getStatus();
+ }
+
+ @Test
+ void confException_constructorCompleto_asignaTodo() {
+ ConfException ex = new ConfException("m", "c", TypeResponse.HTTP_RESPONSE_400);
+ assertEquals("c", ex.getCode());
+ assertEquals(TypeResponse.HTTP_RESPONSE_400, ex.getType());
+ assertEquals(HttpStatus.BAD_REQUEST, ex.getStatus());
+ }
+}
diff --git a/server.services/src/test/java/cl/jonnattan/emulator/utils/UtilitiesTest.java b/server.services/src/test/java/cl/jonnattan/emulator/utils/UtilitiesTest.java
new file mode 100644
index 0000000..a301655
--- /dev/null
+++ b/server.services/src/test/java/cl/jonnattan/emulator/utils/UtilitiesTest.java
@@ -0,0 +1,147 @@
+package cl.jonnattan.emulator.utils;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import cl.jonnattan.emulator.interfaces.ICipher;
+import cl.jonnattan.emulator.interfaces.ISignature;
+
+@ExtendWith(MockitoExtension.class)
+class UtilitiesTest {
+
+ @Mock
+ private EncrypterBusinessLogicService rsaCipher;
+ @Mock
+ private ObjectMapper objectMapper;
+ @Mock
+ private ICipher aesCipher;
+ @Mock
+ private ISignature signature;
+
+ @InjectMocks
+ private Utilities utilities;
+
+ @Test
+ void cksumSHA256_retornaLong() {
+ when(signature.cksum("data")).thenReturn(100L);
+ long result = utilities.cksumSHA256("data");
+ assertTrue(result > 100L);
+ }
+
+ @Test
+ void sha256_delegaEnSignature() {
+ when(signature.getSignature("x")).thenReturn("HASH");
+ assertEquals("HASH", utilities.SHA256("x"));
+ }
+
+ @Test
+ void decryptRSA_dataNull_retornaVacio() {
+ assertEquals("", utilities.decryptRSA(null));
+ }
+
+ @Test
+ void decryptRSA_error_retornaVacio() throws Exception {
+ when(rsaCipher.decrypt(any())).thenThrow(new RuntimeException("boom"));
+ String result = utilities.decryptRSA("YQ=="); // "a" en base64
+ assertEquals("", result);
+ }
+
+ @Test
+ void decryptRSA_ok_retornaTexto() throws Exception {
+ when(rsaCipher.decrypt(any())).thenReturn("hola".getBytes());
+ String result = utilities.decryptRSA("YQ==");
+ assertEquals("hola", result);
+ }
+
+ @Test
+ void encryptRSA_dataNull_retornaVacio() {
+ assertEquals("", utilities.encryptRSA(null));
+ }
+
+ @Test
+ void encryptRSA_ok_retornaBase64() throws Exception {
+ when(rsaCipher.encrypt(any())).thenReturn("hola".getBytes());
+ String result = utilities.encryptRSA("hola");
+ assertNotNull(result);
+ assertTrue(result.length() > 0);
+ }
+
+ @Test
+ void encryptRSA_error_retornaVacio() throws Exception {
+ when(rsaCipher.encrypt(any())).thenThrow(new RuntimeException("boom"));
+ assertEquals("", utilities.encryptRSA("hola"));
+ }
+
+ @Test
+ void toJson_objNull_retornaNULL() {
+ assertEquals("NULL", utilities.toJson(null));
+ }
+
+ @Test
+ void toJson_ok_serializa() throws Exception {
+ when(objectMapper.writeValueAsString(any())).thenReturn("{\"a\":1}");
+ assertEquals("{\"a\":1}", utilities.toJson(new Object()));
+ }
+
+ @Test
+ void toJson_error_retornaTextoError() throws Exception {
+ when(objectMapper.writeValueAsString(any())).thenThrow(new JsonProcessingException("boom") {
+ private static final long serialVersionUID = 1L;
+ });
+ assertEquals("ERROR Convirtiendo a JSON", utilities.toJson(new Object()));
+ }
+
+ @Test
+ void toMap_error_retornaNull() throws Exception {
+ when(objectMapper.readValue(any(String.class), any(Class.class))).thenThrow(new NullPointerException("boom"));
+ assertEquals(null, utilities.toMap("{}"));
+ }
+
+ @Test
+ void toMap_ok_retornaMap() throws Exception {
+ Map expected = new HashMap<>();
+ expected.put("k", "v");
+ when(objectMapper.readValue(any(String.class), any(Class.class))).thenReturn(expected);
+ assertEquals(expected, utilities.toMap("{}"));
+ }
+
+ @Test
+ void decryptAES_null_retornaVacio() {
+ assertEquals("", utilities.decryptAES(null));
+ }
+
+ @Test
+ void decryptAES_ok_retornaPlano() throws Exception {
+ when(aesCipher.decrypt("CIPHER")).thenReturn("PLANO");
+ assertEquals("PLANO", utilities.decryptAES("CIPHER"));
+ }
+
+ @Test
+ void decryptAES_error_retornaVacio() throws Exception {
+ when(aesCipher.decrypt(any())).thenThrow(new RuntimeException("boom"));
+ assertEquals("", utilities.decryptAES("CIPHER"));
+ }
+
+ @Test
+ void getTokenCard_retornaVeinteCaracteres() {
+ when(signature.getSignature(any()))
+ .thenReturn("abcdef0123456789abcdef0123456789abcdef0123456789");
+ String result = utilities.getTokenCard("data");
+ assertEquals(20, result.length());
+ }
+}