Commit de6e3ef3 by Antonio Rueda

Autenticación básica HTTP mediante Spring Security para acceso al API.

parent 9e6ce320
......@@ -34,6 +34,11 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
......
......@@ -11,7 +11,8 @@ import org.springframework.boot.autoconfigure.domain.EntityScan;
@SpringBootApplication(scanBasePackages={
"es.ujaen.dae.ujacoin.servicios",
"es.ujaen.dae.ujacoin.repositorios",
"es.ujaen.dae.ujacoin.controladoresREST"
"es.ujaen.dae.ujacoin.controladoresREST",
"es.ujaen.dae.ujacoin.seguridad"
})
@EntityScan(basePackages="es.ujaen.dae.ujacoin.entidades")
public class UjaCoinApp {
......
......@@ -74,8 +74,8 @@ public class ControladorREST {
/** Login de clientes (temporal hasta incluir autenticación mediante Spring Security */
@GetMapping("/clientes/{dni}")
ResponseEntity<DTOCliente> loginCliente(@PathVariable String dni, @RequestParam String clave) {
Optional<Cliente> cliente = servicios.loginCliente(dni, clave);
ResponseEntity<DTOCliente> verCliente(@PathVariable String dni) {
Optional<Cliente> cliente = servicios.verCliente(dni);
return cliente
.map(c -> ResponseEntity.ok(new DTOCliente(c)))
.orElse(ResponseEntity.notFound().build());
......
package es.ujaen.dae.ujacoin.entidades;
import es.ujaen.dae.ujacoin.util.ExprReg;
import es.ujaen.dae.ujacoin.util.CodificadorMd5;
import es.ujaen.dae.ujacoin.util.CodificadorPassword;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.ArrayList;
......@@ -80,7 +80,8 @@ public class Cliente implements Serializable {
this.tlf = tlf;
this.email = email;
this.clave = (clave != null ? CodificadorMd5.codificar(clave) : null);
this.clave = (clave != null ? CodificadorPassword.codificar(clave) : null);
// this.clave = clave;
tarjetas = new ArrayList<>();
cuentas = new ArrayList<>();
......@@ -116,7 +117,12 @@ public class Cliente implements Serializable {
* @return
*/
public boolean claveValida(String clave) {
return this.clave.equals(CodificadorMd5.codificar(clave));
return CodificadorPassword.igual(clave, this.clave);
//return this.clave.equals(clave);
}
public String getClave() {
return clave;
}
/**
......
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package es.ujaen.dae.ujacoin.seguridad;
import es.ujaen.dae.ujacoin.entidades.Cliente;
import es.ujaen.dae.ujacoin.servicios.ServicioUjaCoin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
/**
* Servicio que proporciona los datos del cliente
* @author ajrueda
*/
@Service
public class ServicioDatosCliente implements UserDetailsService {
@Autowired
ServicioUjaCoin servicioUjaCoin;
PasswordEncoder encoder;
public ServicioDatosCliente() {
encoder = new BCryptPasswordEncoder();
}
PasswordEncoder getEncoder() {
return encoder;
}
@Override
public UserDetails loadUserByUsername(String dni) throws UsernameNotFoundException {
Cliente cliente = servicioUjaCoin.verCliente(dni)
.orElseThrow(() -> new UsernameNotFoundException(""));
return User.withUsername(cliente.getDni())
.roles("CLIENTE").password(cliente.getClave())
.build();
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package es.ujaen.dae.ujacoin.seguridad;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
/**
* Proveedor de datos de seguridad de UJaCoin
*
* @author ajrueda
*/
@Configuration
@EnableWebSecurity
public class ServicioSeguridadUjaCoin extends WebSecurityConfigurerAdapter {
@Autowired
ServicioDatosCliente servicioDatosCliente;
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(servicioDatosCliente)
.passwordEncoder(new BCryptPasswordEncoder());
// auth.inMemoryAuthentication()
// .withUser("ujacoin").roles("CLIENTE").password("{noop}secret");
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable();
httpSecurity.httpBasic();
httpSecurity.authorizeRequests().antMatchers(HttpMethod.POST, "/ujacoin/clientes").anonymous();
// Permitir el acceso de un cliente sólo a sus recursos asociados (datos personales, cuentas, tarjetas, etc.)
httpSecurity.authorizeRequests().antMatchers("/ujacoin/clientes/{dni}/**")
.access("hasRole('CLIENTE') and #dni == principal.username");
}
}
......@@ -83,6 +83,21 @@ public class ServicioUjaCoin {
}
/**
* Realiza un login de un cliente
* @param dni el DNI del cliente
* @param clave la clave de acceso
* @return el objeto de la clase Cliente asociado
*/
@Transactional
public Optional<Cliente> verCliente(@NotBlank String dni) {
Optional<Cliente> clienteLogin = repositorioClientes.buscar(dni);
// Asegurarnos de que se devuelve el cliente con los datos precargados
clienteLogin.ifPresent(c -> c.verCuentas().size());
return clienteLogin;
}
/**
* Crear una cuenta adicional para el cliente
* @param dni el DNI delcliente
* @return la cuenta creada
......
package es.ujaen.dae.ujacoin.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
/**
* Codificador sencillo para contraseñas basado en Md5 (no seguro)
* @author ajrueda
*/
public class CodificadorMd5 {
public class CodificadorPassword {
static BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
private CodificadorMd5() {
private CodificadorPassword() {
}
public static String codificar(String cadena) {
/*
String cadenaCodificada = null;
try {
......@@ -25,6 +26,11 @@ public class CodificadorMd5 {
// No debe ocurrir puesto que MD5 es un algoritmo que existe en la
// implementación Java estándar
}
return cadenaCodificada;
*/
return encoder.encode(cadena);
}
public static boolean igual(String password, String passwordCodificado) {
return encoder.matches(password, passwordCodificado);
}
}
......@@ -26,7 +26,8 @@ import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
/**
* Test para controlador REST de clientes
* Test para controlador REST de clientes
*
* @author ajrueda
*/
@SpringBootTest(classes = es.ujaen.dae.ujacoin.app.UjaCoinApp.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
......@@ -36,24 +37,26 @@ public class ControladorRESTTest {
ServicioLimpiadoBaseDatos limpiadorBaseDatos;
@LocalServerPort
int localPort;
int localPort;
@Autowired
MappingJackson2HttpMessageConverter springBootJacksonConverter;
TestRestTemplate restTemplate;
/** Crear un TestRestTemplate para las pruebas */
MappingJackson2HttpMessageConverter springBootJacksonConverter;
RestTemplateBuilder restTemplateBuilder;
/**
* Crear un TestRestTemplate para las pruebas
*/
@PostConstruct
void crearRestTemplate() {
RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder()
void crearRestTemplateBuilder() {
restTemplateBuilder = new RestTemplateBuilder()
.rootUri("http://localhost:" + localPort + "/ujacoin")
.additionalMessageConverters(List.of(springBootJacksonConverter));
restTemplate = new TestRestTemplate(restTemplateBuilder);
}
/** Intento de creación de un cliente inválido */
}
/**
* Intento de creación de un cliente inválido
*/
@Test
public void testAltaClienteInvalido() {
// Cliente con e-mail incorrecto!!!
......@@ -65,17 +68,20 @@ public class ControladorRESTTest {
"988674533",
"jeegmail.com",
"clave");
TestRestTemplate restTemplate = new TestRestTemplate(restTemplateBuilder);
ResponseEntity<DTOCuenta> respuesta = restTemplate.postForEntity(
"/clientes",
cliente,
"/clientes",
cliente,
DTOCuenta.class
);
Assertions.assertThat(respuesta.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
}
/** test de alta y login de cliente */
/**
* test de alta y login de cliente
*/
@Test
public void testAltaYLoginClienteCuenta() {
DTOCliente cliente = new DTOCliente(
......@@ -87,27 +93,33 @@ public class ControladorRESTTest {
"jee@gmail.com",
"clave");
TestRestTemplate restTemplate = new TestRestTemplate(restTemplateBuilder);
ResponseEntity<DTOCuenta> respuestaAlta = restTemplate.postForEntity(
"/clientes",
cliente,
"/clientes",
cliente,
DTOCuenta.class
);
Assertions.assertThat(respuestaAlta.getStatusCode()).isEqualTo(HttpStatus.CREATED);
ResponseEntity<DTOCliente> respuestaLogin = restTemplate.getForEntity(
"/clientes/{dni}?clave={clave}",
DTOCliente.class,
cliente.getDni(), cliente.getClave()
);
TestRestTemplate restTemplateAutenticado = new TestRestTemplate(restTemplateBuilder.basicAuthentication(cliente.getDni(), cliente.getClave()));
ResponseEntity<DTOCliente> respuestaLogin = restTemplateAutenticado
.getForEntity(
"/clientes/{dni}",
DTOCliente.class,
cliente.getDni(), cliente.getClave()
);
Assertions.assertThat(respuestaLogin.getStatusCode()).isEqualTo(HttpStatus.OK);
DTOCliente clienteLogin = respuestaLogin.getBody();
Assertions.assertThat(clienteLogin.getDni()).isEqualTo(cliente.getDni());
Assertions.assertThat(clienteLogin.getDni()).isEqualTo(cliente.getDni());
}
/** Creación de cuenta adicional */
/**
* Creación de cuenta adicional
*/
@Test
public void testCuentaAdicional() {
DTOCliente cliente = new DTOCliente(
......@@ -119,36 +131,42 @@ public class ControladorRESTTest {
"jee@gmail.com",
"clave");
TestRestTemplate restTemplate = new TestRestTemplate(restTemplateBuilder);
restTemplate.postForEntity(
"/clientes",
cliente,
"/clientes",
cliente,
DTOCuenta.class
);
ResponseEntity<DTOCuenta> respuesta = restTemplate.postForEntity(
"/clientes/{dni}/cuentas",
null,
DTOCuenta.class,
cliente.getDni()
);
TestRestTemplate restTemplateAutenticado = new TestRestTemplate(restTemplateBuilder.basicAuthentication(cliente.getDni(), cliente.getClave()));
ResponseEntity<DTOCuenta> respuesta = restTemplateAutenticado
.postForEntity(
"/clientes/{dni}/cuentas",
null,
DTOCuenta.class,
cliente.getDni()
);
Assertions.assertThat(respuesta.getStatusCode()).isEqualTo(HttpStatus.CREATED);
DTOCuenta[] cuentas = restTemplate.getForEntity(
"/clientes/{dni}/cuentas",
DTOCuenta[].class,
cliente.getDni()
).getBody();
DTOCuenta[] cuentas = restTemplateAutenticado
.getForEntity(
"/clientes/{dni}/cuentas",
DTOCuenta[].class,
cliente.getDni()
).getBody();
Assertions.assertThat(cuentas).hasSize(2);
Assertions.assertThat(cuentas[0].getNum()).isNotEqualTo(cuentas[1].getNum());
}
/** Test de creación de tarjeta */
/**
* Test de creación de tarjeta
*/
@Test
public void testAnadirTarjetaACliente() {
// Registrar cliente
DTOCliente cliente = new DTOCliente(
DTOCliente cliente = new DTOCliente(
"11995667D",
"Juan España España",
LocalDate.of(1990, 11, 1),
......@@ -157,39 +175,46 @@ public class ControladorRESTTest {
"jee@gmail.com",
"clave");
TestRestTemplate restTemplate = new TestRestTemplate(restTemplateBuilder);
restTemplate.postForEntity("/clientes", cliente, DTOCuenta.class);
DTOTarjeta tarjeta = new DTOTarjeta("4111111111111111", cliente.getNombre(), LocalDate.of(2022, 12, 1), "365");
ResponseEntity<DTOTarjeta> respuesta = restTemplate.postForEntity(
"/clientes/{dni}/tarjetas",
tarjeta,
DTOTarjeta.class,
cliente.getDni()
);
TestRestTemplate restTemplateAutenticado = new TestRestTemplate(restTemplateBuilder.basicAuthentication(cliente.getDni(), cliente.getClave()));
ResponseEntity<DTOTarjeta> respuesta = restTemplateAutenticado
.postForEntity(
"/clientes/{dni}/tarjetas",
tarjeta,
DTOTarjeta.class,
cliente.getDni()
);
Assertions.assertThat(respuesta.getStatusCode()).isEqualTo(HttpStatus.CREATED);
respuesta = restTemplate.getForEntity(
"/clientes/{dni}/tarjetas/{num}",
DTOTarjeta.class,
cliente.getDni(),
tarjeta.getNum()
);
respuesta = restTemplateAutenticado
.getForEntity(
"/clientes/{dni}/tarjetas/{num}",
DTOTarjeta.class,
cliente.getDni(),
tarjeta.getNum()
);
Assertions.assertThat(respuesta.getStatusCode()).isEqualTo(HttpStatus.OK);
DTOTarjeta tarjetaRecibida = respuesta.getBody();
Assertions.assertThat(tarjetaRecibida.getNum()).isEqualTo(tarjeta.getNum());
Assertions.assertThat(tarjetaRecibida.getTitular()).isEqualTo(tarjeta.getTitular());
Assertions.assertThat(tarjetaRecibida.getFechaCaducidad()).isEqualTo(tarjeta.getFechaCaducidad());
Assertions.assertThat(tarjetaRecibida.getCvc()).isEqualTo(tarjeta.getCvc());
}
/** Test de ingreso en cuenta */
}
/**
* Test de ingreso en cuenta
*/
@Test
public void testIngreso() {
// Registrar cliente
DTOCliente cliente = new DTOCliente(
// Registrar cliente
DTOCliente cliente = new DTOCliente(
"11995667D",
"Juan España España",
LocalDate.of(1990, 11, 1),
......@@ -197,65 +222,72 @@ public class ControladorRESTTest {
"988674533",
"jee@gmail.com",
"clave"
);
);
TestRestTemplate restTemplate = new TestRestTemplate(restTemplateBuilder);
DTOCuenta cuenta = restTemplate.postForEntity(
"/clientes",
cliente,
"/clientes",
cliente,
DTOCuenta.class
).getBody();
DTOTarjeta tarjeta = new DTOTarjeta(
"4111111111111111",
cliente.getNombre(),
LocalDate.of(2022, 12, 1),
"4111111111111111",
cliente.getNombre(),
LocalDate.of(2022, 12, 1),
"365"
);
restTemplate.postForEntity(
"/clientes/{dni}/tarjetas",
tarjeta,
DTOTarjeta.class,
cliente.getDni()
);
TestRestTemplate restTemplateAutenticado = new TestRestTemplate(restTemplateBuilder.basicAuthentication(cliente.getDni(), cliente.getClave()));
restTemplateAutenticado
.postForEntity(
"/clientes/{dni}/tarjetas",
tarjeta,
DTOTarjeta.class,
cliente.getDni()
);
// Realizar ingreso y comprobar estado de la cuenta
DTOMovimiento ingreso = DTOMovimiento.ingreso(tarjeta.getNum(), 1000);
ResponseEntity<Void> respuestaRegistroMovimiento = restTemplate.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
ingreso,
Void.class,
cliente.getDni(), cuenta.getNum()
);
ResponseEntity<Void> respuestaRegistroMovimiento = restTemplateAutenticado
.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
ingreso,
Void.class,
cliente.getDni(), cuenta.getNum()
);
Assertions.assertThat(respuestaRegistroMovimiento.getStatusCode()).isEqualTo(HttpStatus.CREATED);
// Refrescar estado de la cuenta y comprobar saldo
cuenta = restTemplate.getForObject("/clientes/{dni}/cuentas/{num}",
DTOCuenta.class,
cliente.getDni(), cuenta.getNum());
cuenta = restTemplateAutenticado
.getForObject("/clientes/{dni}/cuentas/{num}",
DTOCuenta.class,
cliente.getDni(), cuenta.getNum());
Assertions.assertThat(cuenta.getSaldo()).isEqualTo(1000);
ResponseEntity<DTOMovimiento[]> respuestaListadoMovimientos = restTemplate.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
DTOMovimiento[].class,
cliente.getDni(), cuenta.getNum()
);
ResponseEntity<DTOMovimiento[]> respuestaListadoMovimientos = restTemplateAutenticado
.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
DTOMovimiento[].class,
cliente.getDni(), cuenta.getNum()
);
DTOMovimiento[] movimientos = respuestaListadoMovimientos.getBody();
Assertions.assertThat(movimientos).hasSize(1);
Assertions.assertThat(movimientos[0].getTipo()).isEqualTo(DTOMovimiento.INGRESO);
Assertions.assertThat(movimientos[0].getImporte()).isEqualTo(ingreso.getImporte());
}
/** Test de transferencia entre cuentas */
}
/**
* Test de transferencia entre cuentas
*/
@Test
public void testTransferencia() {
// Registrar cliente
DTOCliente cliente = new DTOCliente(
// Registrar cliente
DTOCliente cliente = new DTOCliente(
"11995667D",
"Juan España España",
LocalDate.of(1990, 11, 1),
......@@ -263,37 +295,39 @@ public class ControladorRESTTest {
"988674533",
"jee@gmail.com",
"clave"
);
);
TestRestTemplate restTemplate = new TestRestTemplate(restTemplateBuilder);
DTOCuenta cuentaOrigen = restTemplate.postForEntity(
"/clientes",
cliente,
"/clientes",
cliente,
DTOCuenta.class
).getBody();
DTOTarjeta tarjeta = new DTOTarjeta(
"4111111111111111",
cliente.getNombre(),
LocalDate.of(2022, 12, 1),
"4111111111111111",
cliente.getNombre(),
LocalDate.of(2022, 12, 1),
"365"
);
restTemplate.postForEntity(
"/clientes/{dni}/tarjetas",
tarjeta,
DTOTarjeta.class,
TestRestTemplate restTemplateAutenticado1 = new TestRestTemplate(restTemplateBuilder.basicAuthentication(cliente.getDni(), cliente.getClave()));
restTemplateAutenticado1.postForEntity(
"/clientes/{dni}/tarjetas",
tarjeta,
DTOTarjeta.class,
cliente.getDni()
);
// Realizar ingreso y comprobar estado de la cuenta
DTOMovimiento ingreso = DTOMovimiento.ingreso(tarjeta.getNum(), 1000);
restTemplate.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
ingreso,
Void.class,
restTemplateAutenticado1.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
ingreso,
Void.class,
cliente.getDni(), cuentaOrigen.getNum()
);
// Crear segundo cliente
DTOCliente cliente2 = new DTOCliente(
"99207668E",
......@@ -302,61 +336,65 @@ public class ControladorRESTTest {
"Cl La Paz, 20 - Jaén",
"670701570",
"pjj@gmail.com",
"clavezzz");
"clavezzz"
);
DTOCuenta cuentaDestino = restTemplate.postForEntity(
"/clientes",
cliente2,
"/clientes",
cliente2,
DTOCuenta.class
).getBody();
).getBody();
// Realizar transferencia
DTOMovimiento transferencia = DTOMovimiento.transferencia(cuentaDestino.getNum(), 500);
restTemplate.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
transferencia,
Void.class,
restTemplateAutenticado1.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
transferencia,
Void.class,
cliente.getDni(), cuentaOrigen.getNum()
);
);
// Refrescar cuenta origen y destino
// Refrescar estados de la cuentas y comprobar saldos
cuentaOrigen = restTemplate.getForObject("/clientes/{dni}/cuentas/{num}",
DTOCuenta.class,
cuentaOrigen = restTemplateAutenticado1.getForObject("/clientes/{dni}/cuentas/{num}",
DTOCuenta.class,
cliente.getDni(), cuentaOrigen.getNum());
Assertions.assertThat(cuentaOrigen.getSaldo()).isEqualTo(500);
cuentaDestino = restTemplate.getForObject("/clientes/{dni}/cuentas/{num}",
DTOCuenta.class,
TestRestTemplate restTemplateAutenticado2 = new TestRestTemplate(restTemplateBuilder.basicAuthentication(cliente2.getDni(), cliente2.getClave()));
cuentaDestino = restTemplateAutenticado2.getForObject("/clientes/{dni}/cuentas/{num}",
DTOCuenta.class,
cliente2.getDni(), cuentaDestino.getNum());
Assertions.assertThat(cuentaDestino.getSaldo()).isEqualTo(500);
// Listar movimientos de la cuenta origen
DTOMovimiento[] movimientos = restTemplate.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
DTOMovimiento[].class,
DTOMovimiento[] movimientos = restTemplateAutenticado1.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
DTOMovimiento[].class,
cliente.getDni(), cuentaOrigen.getNum()
).getBody();
Assertions.assertThat(movimientos).hasSize(2);
Assertions.assertThat(movimientos[1].getTipo()).isEqualTo(DTOMovimiento.TRANSFERENCIA_EMITIDA);
// Listar movimientos de la cuenta destino
movimientos = restTemplate.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
DTOMovimiento[].class,
movimientos = restTemplateAutenticado2.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
DTOMovimiento[].class,
cliente2.getDni(), cuentaDestino.getNum()
).getBody();
Assertions.assertThat(movimientos).hasSize(1);
Assertions.assertThat(movimientos[0].getTipo()).isEqualTo(DTOMovimiento.TRANSFERENCIA_RECIBIDA);
}
/** Reintegro sin saldo suficiente */
}
/**
* Reintegro sin saldo suficiente
*/
@Test
public void testReintegroSinSaldo() {
// Registrar cliente
DTOCliente cliente = new DTOCliente(
// Registrar cliente
DTOCliente cliente = new DTOCliente(
"11995667D",
"Juan España España",
LocalDate.of(1990, 11, 1),
......@@ -364,64 +402,68 @@ public class ControladorRESTTest {
"988674533",
"jee@gmail.com",
"clave"
);
);
TestRestTemplate restTemplate = new TestRestTemplate(restTemplateBuilder);
DTOCuenta cuenta = restTemplate.postForEntity(
"/clientes",
cliente,
"/clientes",
cliente,
DTOCuenta.class
).getBody();
DTOTarjeta tarjeta = new DTOTarjeta(
"4111111111111111",
cliente.getNombre(),
LocalDate.of(2022, 12, 1),
"4111111111111111",
cliente.getNombre(),
LocalDate.of(2022, 12, 1),
"365"
);
restTemplate.postForEntity(
"/clientes/{dni}/tarjetas",
tarjeta,
DTOTarjeta.class,
TestRestTemplate restTemplateAutenticado = new TestRestTemplate(restTemplateBuilder.basicAuthentication(cliente.getDni(), cliente.getClave()));
restTemplateAutenticado.postForEntity(
"/clientes/{dni}/tarjetas",
tarjeta,
DTOTarjeta.class,
cliente.getDni()
);
// Realizar ingreso en cuenta
DTOMovimiento ingreso = DTOMovimiento.ingreso(tarjeta.getNum(), 1000);
restTemplate.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
ingreso,
Void.class,
restTemplateAutenticado.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
ingreso,
Void.class,
cliente.getDni(), cuenta.getNum()
);
// Primer reintegro correcto
DTOMovimiento reintegro = DTOMovimiento.reintegro(tarjeta.getNum(), 1000);
ResponseEntity<Void> respuesta = restTemplate.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
reintegro,
Void.class,
ResponseEntity<Void> respuesta = restTemplateAutenticado.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
reintegro,
Void.class,
cliente.getDni(), cuenta.getNum()
);
Assertions.assertThat(respuesta.getStatusCode()).isEqualTo(HttpStatus.CREATED);
// No hay saldo suficiente para el segundo reintegro
respuesta = restTemplate.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
reintegro,
Void.class,
cliente.getDni(), cuenta.getNum()
);
Assertions.assertThat(respuesta.getStatusCode()).isEqualTo(HttpStatus.PRECONDITION_FAILED);
}
/** Test de listado de movimientos con paginación */
respuesta = restTemplateAutenticado.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
reintegro,
Void.class,
cliente.getDni(), cuenta.getNum()
);
Assertions.assertThat(respuesta.getStatusCode()).isEqualTo(HttpStatus.PRECONDITION_FAILED);
}
/**
* Test de listado de movimientos con paginación
*/
@Test
public void testListadoMovimientosPaginado() {
// Registrar cliente
DTOCliente cliente = new DTOCliente(
public void testListadoMovimientosPaginado() {
// Registrar cliente
DTOCliente cliente = new DTOCliente(
"11995667D",
"Juan España España",
LocalDate.of(1990, 11, 1),
......@@ -429,82 +471,83 @@ public class ControladorRESTTest {
"988674533",
"jee@gmail.com",
"clave"
);
);
TestRestTemplate restTemplate = new TestRestTemplate(restTemplateBuilder);
DTOCuenta cuenta = restTemplate.postForEntity(
"/clientes",
cliente,
"/clientes",
cliente,
DTOCuenta.class
).getBody();
DTOTarjeta tarjeta = new DTOTarjeta(
"4111111111111111",
cliente.getNombre(),
LocalDate.of(2022, 12, 1),
"4111111111111111",
cliente.getNombre(),
LocalDate.of(2022, 12, 1),
"365"
);
restTemplate.postForEntity(
"/clientes/{dni}/tarjetas",
tarjeta,
DTOTarjeta.class,
TestRestTemplate restTemplateAutenticado = new TestRestTemplate(restTemplateBuilder.basicAuthentication(cliente.getDni(), cliente.getClave()));
restTemplateAutenticado.postForEntity(
"/clientes/{dni}/tarjetas",
tarjeta,
DTOTarjeta.class,
cliente.getDni()
);
// Realizar ingreso en cuenta
DTOMovimiento ingreso = DTOMovimiento.ingreso(tarjeta.getNum(), 1000);
float[] importeIngresos = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120};
for (float importe: importeIngresos) {
restTemplate.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
DTOMovimiento.ingreso(tarjeta.getNum(), importe),
Void.class,
for (float importe : importeIngresos) {
restTemplateAutenticado.postForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
DTOMovimiento.ingreso(tarjeta.getNum(), importe),
Void.class,
cliente.getDni(), cuenta.getNum()
);
}
// Obtener primera página (10 elementos)
ResponseEntity<DTOMovimiento[]> respuesta1 = restTemplate.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
DTOMovimiento[].class,
ResponseEntity<DTOMovimiento[]> respuesta1 = restTemplateAutenticado.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos",
DTOMovimiento[].class,
cliente.getDni(), cuenta.getNum()
);
DTOMovimiento[] movimientos = respuesta1.getBody();
Assertions.assertThat(movimientos).hasSize(10);
Assertions.assertThat(movimientos[0].getImporte()).isEqualTo(10);
// Obtener segunda página (2 selementos)
ResponseEntity<DTOMovimiento[]> respuesta2 = restTemplate.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos?pag=2",
DTOMovimiento[].class,
ResponseEntity<DTOMovimiento[]> respuesta2 = restTemplateAutenticado.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos?pag=2",
DTOMovimiento[].class,
cliente.getDni(), cuenta.getNum()
);
movimientos = respuesta2.getBody();
Assertions.assertThat(movimientos).hasSize(2);
Assertions.assertThat(movimientos[0].getImporte()).isEqualTo(110);
// Obtener primera página con 5 elementos solo
ResponseEntity<DTOMovimiento[]> respuesta3 = restTemplate.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos?pag=1&num=5",
DTOMovimiento[].class,
ResponseEntity<DTOMovimiento[]> respuesta3 = restTemplateAutenticado.getForEntity(
"/clientes/{dni}/cuentas/{num}/movimientos?pag=1&num=5",
DTOMovimiento[].class,
cliente.getDni(), cuenta.getNum()
);
movimientos = respuesta3.getBody();
Assertions.assertThat(movimientos).hasSize(5);
Assertions.assertThat(movimientos[0].getImporte()).isEqualTo(10);
Assertions.assertThat(movimientos[0].getImporte()).isEqualTo(10);
}
@BeforeEach
void limpiarBaseDatos() {
limpiadorBaseDatos.limpiar();
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment