diff --git a/010_spring_boot/api_rest/api3/pom.xml b/010_spring_boot/api_rest/api3/pom.xml index 6fd7037..17b51b7 100644 --- a/010_spring_boot/api_rest/api3/pom.xml +++ b/010_spring_boot/api_rest/api3/pom.xml @@ -1,105 +1,111 @@ - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 3.1.3 - - - med.voll - api - 0.0.1-SNAPSHOT - api - API Rest para clínica Voll - - 17 - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-devtools - runtime - true - - - org.projectlombok - lombok - true - - - org.springframework.boot - spring-boot-starter-test - test - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.1.3 + + + med.voll + api + 0.0.1-SNAPSHOT + api + API Rest para clínica Voll + + 17 + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.flywaydb - flyway-core - - - org.flywaydb - flyway-mysql - + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.flywaydb + flyway-core + + + org.flywaydb + flyway-mysql + - - com.mysql - mysql-connector-j - runtime - + + com.mysql + mysql-connector-j + runtime + - - org.springframework.boot - spring-boot-starter-validation - + + org.springframework.boot + spring-boot-starter-validation + - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.security - spring-security-test - test - + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security + spring-security-test + test + - - com.auth0 - java-jwt - 4.4.0 - + + com.auth0 + java-jwt + 4.4.0 + - - org.springdoc - springdoc-openapi-starter-webmvc-ui - 2.2.0 - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - org.projectlombok - lombok - - - - - - + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.2.0 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + diff --git a/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/AutenticacionController.java b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/AutenticacionController.java index 53d93ba..7b56f59 100644 --- a/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/AutenticacionController.java +++ b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/AutenticacionController.java @@ -1,5 +1,6 @@ package med.voll.api.controller; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import med.voll.api.domain.usuario.DatosAutenticacionUsuario; import med.voll.api.domain.usuario.Usuario; @@ -17,6 +18,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/login") +@Tag(name = "Autenticacion", description = "Provee token para usuario, que da acceso a otros endpoints") public class AutenticacionController { @Autowired diff --git a/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/ConsultaController.java b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/ConsultaController.java index b936284..09a8a1a 100644 --- a/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/ConsultaController.java +++ b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/ConsultaController.java @@ -1,5 +1,6 @@ package med.voll.api.controller; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import jakarta.validation.Valid; import med.voll.api.domain.consulta.AgendaDeConsultaService; @@ -26,6 +27,7 @@ public class ConsultaController { @PostMapping @Transactional // ojo de donde se importa esta anotación + @Operation(summary = "Registra una consulta en la base de datos") public ResponseEntity agendar(@RequestBody @Valid DatosAgendarConsulta datos) { System.out.println(datos); var response = service.agendar(datos); @@ -34,6 +36,7 @@ public class ConsultaController { } @GetMapping + @Operation(summary = "Retorna listado de consultas") public ResponseEntity> listar( @PageableDefault(size = 10, sort = {"fecha"}) Pageable paginacion) { var response = service.consultar(paginacion); @@ -42,6 +45,7 @@ public class ConsultaController { @DeleteMapping @Transactional + @Operation(summary = "Cancela una consulta") public ResponseEntity cancelar(@RequestBody @Valid DatosCancelarConsulta dados) { service.cancelar(dados); return ResponseEntity.noContent().build(); diff --git a/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/MedicoController.java b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/MedicoController.java index cd5a9eb..ad503a8 100644 --- a/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/MedicoController.java +++ b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/MedicoController.java @@ -1,5 +1,6 @@ package med.voll.api.controller; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import jakarta.transaction.Transactional; import jakarta.validation.Valid; @@ -24,6 +25,7 @@ public class MedicoController { private MedicoRepository medicoRepository; @PostMapping + @Operation(summary = "Registra un nuevo medico en la base de datos") public ResponseEntity registrarMedico( @RequestBody @Valid DatosRegistroMedico datosRegistroMedico, UriComponentsBuilder uriComponentsBuilder) { @@ -36,6 +38,7 @@ public class MedicoController { } @GetMapping + @Operation(summary = "Retorna listado de medicos") public ResponseEntity> listadoMedicos( @PageableDefault(size = 5) Pageable paginacion) { return ResponseEntity.ok(medicoRepository.findByActivoTrue(paginacion).map(DatosListadoMedicos::new)); @@ -43,6 +46,7 @@ public class MedicoController { @PutMapping @Transactional + @Operation(summary = "Actualiza los datos de un medico existente") public ResponseEntity actualizarMedico( @RequestBody @Valid DatosActualizarMedico datosActualizarMedico) { Medico medico = medicoRepository.getReferenceById(datosActualizarMedico.id()); @@ -55,6 +59,7 @@ public class MedicoController { @DeleteMapping("/{id}") @Transactional + @Operation(summary = "Cambia el estado de un medico a inactivo") public ResponseEntity eliminarMedico(@PathVariable Long id) { Medico medico = medicoRepository.getReferenceById(id); medico.desactivarMedico(); @@ -62,6 +67,7 @@ public class MedicoController { } @GetMapping("/{id}") + @Operation(summary = "Retorna los registros del medico según Id") public ResponseEntity retornaDatosMedico(@PathVariable Long id) { Medico medico = medicoRepository.getReferenceById(id); DatosRespuestaMedico datosRespuestaMedico = new DatosRespuestaMedico( diff --git a/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/PacienteController.java b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/PacienteController.java index 4ee8f15..8bf1836 100644 --- a/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/PacienteController.java +++ b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/PacienteController.java @@ -1,5 +1,6 @@ package med.voll.api.controller; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import jakarta.transaction.Transactional; import jakarta.validation.Valid; @@ -26,6 +27,7 @@ public class PacienteController { private PacienteRepository pacienteRepository; @PostMapping + @Operation(summary = "Registra un nuevo paciente") public ResponseEntity registrarPaciente( @RequestBody @Valid DatosRegistroPaciente datosRegistroPaciente, UriComponentsBuilder uriComponentsBuilder) { @@ -38,6 +40,7 @@ public class PacienteController { } @GetMapping + @Operation(summary = "Retorna listado de pacientes") public ResponseEntity> listadoPacientes( @PageableDefault(size = 5) Pageable paginacion) { return ResponseEntity.ok( @@ -47,6 +50,7 @@ public class PacienteController { @PutMapping @Transactional + @Operation(summary = "Actualiza información del paciente") public ResponseEntity actualizarPaciente( @RequestBody @Valid DatosActualizarPaciente datosActualizarPaciente) { Paciente paciente = pacienteRepository.getReferenceById(datosActualizarPaciente.id()); @@ -60,6 +64,7 @@ public class PacienteController { // Desactivar Paciente @DeleteMapping("/{id}") @Transactional + @Operation(summary = "Cambia el estado de un paciente a inactivo") public ResponseEntity eliminarPaciente(@PathVariable Long id) { Paciente paciente = pacienteRepository.getReferenceById(id); paciente.desactivarPaciente(); @@ -67,6 +72,7 @@ public class PacienteController { } @GetMapping("/{id}") + @Operation(summary = "Retorna los detalles del paciente según ID") public ResponseEntity retornaDatosPaciente(@PathVariable Long id) { Paciente paciente = pacienteRepository.getReferenceById(id); DatosRespuestaPaciente datosRespuestaPaciente = new DatosRespuestaPaciente( diff --git a/010_spring_boot/api_rest/api3/src/main/resources/application-test.yml b/010_spring_boot/api_rest/api3/src/main/resources/application-test.yml new file mode 100644 index 0000000..474c5c3 --- /dev/null +++ b/010_spring_boot/api_rest/api3/src/main/resources/application-test.yml @@ -0,0 +1,5 @@ +spring: + datasource: + url: jdbc:mysql://${TEST_DB_URL}?createDatabaseIfNotExist=true&serverTimezone=UTC + username: ${DB_USER} + password: ${DB_PASS} \ No newline at end of file diff --git a/010_spring_boot/api_rest/api3/src/test/java/med/voll/api/ApiApplicationTests.java b/010_spring_boot/api_rest/api3/src/test/java/med/voll/api/ApiApplicationTests.java deleted file mode 100644 index eb360a5..0000000 --- a/010_spring_boot/api_rest/api3/src/test/java/med/voll/api/ApiApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package med.voll.api; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class ApiApplicationTests { - - @Test - void contextLoads() { - } - -} diff --git a/010_spring_boot/api_rest/api3/src/test/java/med/voll/api/controller/ConsultaControllerTest.java b/010_spring_boot/api_rest/api3/src/test/java/med/voll/api/controller/ConsultaControllerTest.java new file mode 100644 index 0000000..4f0fb35 --- /dev/null +++ b/010_spring_boot/api_rest/api3/src/test/java/med/voll/api/controller/ConsultaControllerTest.java @@ -0,0 +1,88 @@ +package med.voll.api.controller; + +import med.voll.api.domain.consulta.AgendaDeConsultaService; +import med.voll.api.domain.consulta.DatosAgendarConsulta; +import med.voll.api.domain.consulta.DatosDetalleConsulta; +import med.voll.api.domain.medico.Especialidad; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.json.AutoConfigureJsonTesters; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.json.JacksonTester; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +import java.time.LocalDateTime; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; + +@SpringBootTest +@AutoConfigureMockMvc +@AutoConfigureJsonTesters +@ActiveProfiles("test") +class ConsultaControllerTest { + + @Autowired + private MockMvc mvc; + + @Autowired + private JacksonTester agendarConsultaJacksonTester; + + @Autowired + private JacksonTester detalleConsultaJacksonTester; + + @MockBean + private AgendaDeConsultaService agendaDeConsultaService; + + @Test + @DisplayName("Debe retornar estado http 400 cuando datos ingresados no sean válidos") + @WithMockUser + void agendarEscenario1() throws Exception { + // given - when + var response = mvc.perform(post("/consultas")).andReturn().getResponse(); + // then + assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatus()); + } + + @Test + @DisplayName("Debe retornar estado http 200 cuando datos ingresados sean válidos") + @WithMockUser + void agendarEscenario2() throws Exception { + + //given + var fecha = LocalDateTime.now().plusHours(1); + var especialidad = Especialidad.CARDIOLOGIA; + var datos = new DatosDetalleConsulta(null,2l,5l,fecha); + + // when + when(agendaDeConsultaService.agendar(any())).thenReturn(datos); + + var response = mvc.perform(post("/consultas") + .contentType(MediaType.APPLICATION_JSON) + .content(agendarConsultaJacksonTester.write( + new DatosAgendarConsulta( + 2l, + 5l, + fecha, + especialidad)) + .getJson())) + .andReturn().getResponse(); + + //then + assertEquals(HttpStatus.OK.value(), response.getStatus()); + + var jsonEsperado = detalleConsultaJacksonTester.write(datos).getJson(); + + assertEquals(response.getContentAsString(), jsonEsperado); + } + +} \ No newline at end of file diff --git a/010_spring_boot/api_rest/api3/src/test/java/med/voll/api/domain/medico/MedicoRepositoryTest.java b/010_spring_boot/api_rest/api3/src/test/java/med/voll/api/domain/medico/MedicoRepositoryTest.java new file mode 100644 index 0000000..8bf493c --- /dev/null +++ b/010_spring_boot/api_rest/api3/src/test/java/med/voll/api/domain/medico/MedicoRepositoryTest.java @@ -0,0 +1,115 @@ +package med.voll.api.domain.medico; + +import med.voll.api.domain.consulta.Consulta; +import med.voll.api.domain.direccion.DatosDireccion; +import med.voll.api.domain.paciente.DatosRegistroPaciente; +import med.voll.api.domain.paciente.Paciente; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; +import org.springframework.test.context.ActiveProfiles; + +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.temporal.TemporalAdjuster; +import java.time.temporal.TemporalAdjusters; + +import static org.junit.jupiter.api.Assertions.*; + +@DataJpaTest +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@ActiveProfiles("test") +class MedicoRepositoryTest { + + @Autowired + private MedicoRepository medicoRepository; + @Autowired + private TestEntityManager em; + + @Test + @DisplayName("Debe retornar null cuando el médico tenga una consulta en ese horario") + void seleccionarMedicoConEspecialidadEnFechaEscenario1() { + + var proximoLunes10H = LocalDate.now() + .with(TemporalAdjusters.next(DayOfWeek.MONDAY)) + .atTime(10, 0); + + var medico = registrarMedico("Jose","jose@mail.com", "123456", Especialidad.CARDIOLOGIA); + var paciente = registrarPaciente("antonio","antonio@mail.com","654321"); + registrarConsulta(medico, paciente, proximoLunes10H); + + var medicoLibre = medicoRepository.seleccionarMedicoConEspecialidadEnFecha( + Especialidad.CARDIOLOGIA, + proximoLunes10H) ; + assertNull(medicoLibre); + } + + @Test + @DisplayName("Debe retornar el médico ingresado como disponible en ese horario") + void seleccionarMedicoConEspecialidadEnFechaEscenario2() { + + var proximoLunes10H = LocalDate.now() + .with(TemporalAdjusters.next(DayOfWeek.MONDAY)) + .atTime(10, 0); + + var medico = registrarMedico("Jose","jose@mail.com", "123456", Especialidad.CARDIOLOGIA); + + var medicoLibre = medicoRepository.seleccionarMedicoConEspecialidadEnFecha( + Especialidad.CARDIOLOGIA, + proximoLunes10H) ; + + assertEquals(medicoLibre, medico); + } + + private void registrarConsulta(Medico medico, Paciente paciente, LocalDateTime fecha) { + em.persist(new Consulta(null, medico, paciente, fecha, null)); + } + + private Medico registrarMedico(String nombre, String email, String documento, Especialidad especialidad) { + var medico = new Medico(datosMedico(nombre, email, documento, especialidad)); + em.persist(medico); + return medico; + } + + private Paciente registrarPaciente(String nombre, String email, String documento) { + var paciente = new Paciente(datosPaciente(nombre, email, documento)); + em.persist(paciente); + return paciente; + } + + private DatosRegistroMedico datosMedico(String nombre, String email, String documento, Especialidad especialidad) { + return new DatosRegistroMedico( + nombre, + email, + "61999999999", + documento, + especialidad, + datosDireccion() + ); + } + + private DatosRegistroPaciente datosPaciente(String nombre, String email, String documento) { + return new DatosRegistroPaciente( + nombre, + email, + "61999999999", + documento, + datosDireccion() + ); + } + + private DatosDireccion datosDireccion() { + return new DatosDireccion( + "loca", + "azul", + "Acapulco", + "321", + "12" + ); + } + +} \ No newline at end of file diff --git a/010_spring_boot/spring_boot_3.md b/010_spring_boot/spring_boot_3.md index a6814f3..8d9cc41 100644 --- a/010_spring_boot/spring_boot_3.md +++ b/010_spring_boot/spring_boot_3.md @@ -969,3 +969,253 @@ por token. --- +## Pruebas Automatizadas + +***¿Que se prueba?*** + +- Cotroller -> API +- Services -> Reglas de Negocio +- Repository -> Queries + +#### Tipos de Tests + +- Test de caja negra +- Test de caja blanca + +### Propiedades de los Tests + +[application-test.yml](./api_rest/api3/src/main/resources/application-test.yml) + +```yml +spring: + datasource: + url: jdbc:mysql://${TEST_DB_URL}?createDatabaseIfNotExist=true&serverTimezone=UTC + username: ${DB_USER} + password: ${DB_PASS} +``` + +### Creación de Tests + +#### Test MedicoRepository + +Se crea el *Package* +[`test.java.med.voll.api.domain.medico`](./api_rest/api3/src/test/java/med/voll/api/domain/medico/) +y la clase +[MedicoRepositoryTest](./api_rest/api3/src/test/java/med/voll/api/domain/medico/MedicoRepositoryTest.java) + +```java +@DataJpaTest +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@ActiveProfiles("test") +class MedicoRepositoryTest { + + @Autowired + private MedicoRepository medicoRepository; + @Autowired + private TestEntityManager em; + + @Test + @DisplayName("Debe retornar null cuando el médico tenga una consulta en ese horario") + void seleccionarMedicoConEspecialidadEnFechaEscenario1() { + + var proximoLunes10H = LocalDate.now() + .with(TemporalAdjusters.next(DayOfWeek.MONDAY)) + .atTime(10, 0); + + var medico = registrarMedico("Jose", + "jose@mail.com", + "123456", + Especialidad.CARDIOLOGIA); + var paciente = registrarPaciente("antonio","antonio@mail.com","654321"); + registrarConsulta(medico, paciente, proximoLunes10H); + + var medicoLibre = medicoRepository.seleccionarMedicoConEspecialidadEnFecha( + Especialidad.CARDIOLOGIA, + proximoLunes10H); + assertNull(medicoLibre); + } + + @Test + @DisplayName("Debe retornar el médico ingresado como disponible en ese horario") + void seleccionarMedicoConEspecialidadEnFechaEscenario2() { + + var proximoLunes10H = LocalDate.now() + .with(TemporalAdjusters.next(DayOfWeek.MONDAY)) + .atTime(10, 0); + + var medico = registrarMedico("Jose", + "jose@mail.com", + "123456", + Especialidad.CARDIOLOGIA); + var medicoLibre = medicoRepository.seleccionarMedicoConEspecialidadEnFecha( + Especialidad.CARDIOLOGIA, + proximoLunes10H) ; + + assertEquals(medicoLibre, medico); + } + + private void registrarConsulta(Medico medico, + Paciente paciente, + LocalDateTime fecha) { + em.persist(new Consulta(null, medico, paciente, fecha, null)); + } + + private Medico registrarMedico(String nombre, + String email, + String documento, + Especialidad especialidad) { + var medico = new Medico(datosMedico(nombre, email, documento, especialidad)); + em.persist(medico); + return medico; + } + + private Paciente registrarPaciente(String nombre, + String email, + String documento) { + var paciente = new Paciente(datosPaciente(nombre, email, documento)); + em.persist(paciente); + return paciente; + } + + private DatosRegistroMedico datosMedico(String nombre, + String email, + String documento, + Especialidad especialidad) { + return new DatosRegistroMedico( + nombre, + email, + "61999999999", + documento, + especialidad, + datosDireccion() + ); + } + + private DatosRegistroPaciente datosPaciente(String nombre, + String email, + String documento) { + return new DatosRegistroPaciente( + nombre, + email, + "61999999999", + documento, + datosDireccion() + ); + } + + private DatosDireccion datosDireccion() { + return new DatosDireccion( + "Loca", + "Azul", + "Acapulco", + "321", + "12" + ); + } + +} +``` + +### Test ConsultaController + +Clase +[ConsultaControllerTest](./api_rest/api3/src/test/java/med/voll/api/controller/ConsultaControllerTest.java) +en *package* +[`test.java.med.voll.api.controler`](./api_rest/api3/src/test/java/med/voll/api/controller/) + +```java +package med.voll.api.controller; + +import med.voll.api.domain.consulta.AgendaDeConsultaService; +import med.voll.api.domain.consulta.DatosAgendarConsulta; +import med.voll.api.domain.consulta.DatosDetalleConsulta; +import med.voll.api.domain.medico.Especialidad; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.json.AutoConfigureJsonTesters; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.json.JacksonTester; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +import java.time.LocalDateTime; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; + +@SpringBootTest +@AutoConfigureMockMvc +@AutoConfigureJsonTesters +@ActiveProfiles("test") +class ConsultaControllerTest { + + @Autowired + private MockMvc mvc; + + @Autowired + private JacksonTester agendarConsultaJacksonTester; + + @Autowired + private JacksonTester detalleConsultaJacksonTester; + + @MockBean + private AgendaDeConsultaService agendaDeConsultaService; + + @Test + @DisplayName("Debe retornar estado http 400 cuando datos ingresados no sean válidos") + @WithMockUser + void agendarEscenario1() throws Exception { + // given - when + var response = mvc.perform(post("/consultas")).andReturn().getResponse(); + // then + assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatus()); + } + + @Test + @DisplayName("Debe retornar estado http 200 cuando datos ingresados sean válidos") + @WithMockUser + void agendarEscenario2() throws Exception { + + //given + var fecha = LocalDateTime.now().plusHours(1); + var especialidad = Especialidad.CARDIOLOGIA; + var datos = new DatosDetalleConsulta(null,2l,5l,fecha); + + // when + when(agendaDeConsultaService.agendar(any())).thenReturn(datos); + + var response = mvc.perform(post("/consultas") + .contentType(MediaType.APPLICATION_JSON) + .content(agendarConsultaJacksonTester.write( + new DatosAgendarConsulta( + 2l, + 5l, + fecha, + especialidad)) + .getJson())) + .andReturn().getResponse(); + + //then + assertEquals(HttpStatus.OK.value(), response.getStatus()); + + var jsonEsperado = detalleConsultaJacksonTester.write(datos).getJson(); + + assertEquals(response.getContentAsString(), jsonEsperado); + } + +} +``` + +--- + +## Build del proyecto + +