Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adicionar controller v2 para validar com @validated #79

Merged
merged 6 commits into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions tjf-api-samples/tjf-api-core-exception-sample/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,31 @@ public class StarshipController {

A mágica acontece dentro do método `createStarship` que possui a validação dos objetos que dispara nossa exceção criada anteriormente.

Existe outra forma de realizar as validações com as anotações @ApiValidated e @ApiValid, para exemplificar criaremos a V2 do controller:

```java
@RestController
@RequestMapping(path = StarshipControllerV2.PATH, produces = APPLICATION_JSON_VALUE)
@ApiGuideline(ApiGuidelineVersion.V2)
@ApiValidated(status = HttpStatus.BAD_GATEWAY, value = "StarshipCreateConstraintException")
public class StarshipControllerV2 {

public static final String PATH = "api/v2/starship";

@PostMapping(path = "/create")
@ResponseStatus(code = HttpStatus.CREATED)
public String createStarship2(@RequestBody @ApiValid Starship dto) {
return "{\"starship\":\"created\"}";
}

@PostMapping(path = "/exception")
public Starship exceptionStarship2(@RequestBody @ApiValid Starship dto) {
throw new RuntimeException();
}
}
```
A anotação `@ApiValid` realiza a validação dos dados da espaçonave quando aplicada no controller. Caso ocorra uma violação nas regras de validação, será lançada a exceção `StarshipCreateConstraintException`, conforme especificado pela anotação `@ApiValidated`.

Agora antes de testarmos, precisamos criar as mensagens de validação e exceção das classes `Starship` e `StarshipCreateConstraintException`. Para isso crie a seguinte estrutura de mensagens.

Lembre-se que conforme a documentação do módulo **i18n Core** as mensagens devem seguir o padrão de caracteres _unicode_.
Expand Down Expand Up @@ -185,6 +210,36 @@ Content-Type: application/json

E teremos nosso retorno de erro:

```Json
{
"code": "StarshipCreateConstraintException",
"message": "É uma armadilha",
"detailedMessage": "A força não está com você",
"details": [
{
"code": "Starship.description.Size",
"message": "A descrição da nave não deve ser menor que 1 ou maior que 15",
"detailedMessage": "description: A sucata mais veloz da galáxia"
}
]
}
```
Também testaremos o controller V2

```http
POST /api/v1/starship/create HTTP/1.1
Host: localhost:8080
Content-Type: application/json

{
"name": "Millenium Falcon",
"description": "A sucata mais veloz da galáxia",
"crew": 5
}
```

E teremos nosso retorno de erro:

```Json
{
"code": "StarshipCreateConstraintException",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.tjf.sample.github.apicore.exception.controller;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.tjf.sample.github.apicore.exception.exception.StarshipCreateConstraintException;
import com.tjf.sample.github.apicore.exception.model.Starship;
import com.totvs.tjf.api.context.stereotype.ApiError;
import com.totvs.tjf.api.context.stereotype.ApiGuideline;
import com.totvs.tjf.api.context.stereotype.ApiGuideline.ApiGuidelineVersion;
import com.totvs.tjf.api.validation.stereotype.ApiValid;
import com.totvs.tjf.api.validation.stereotype.ApiValidated;

import jakarta.websocket.server.PathParam;

@RestController
@RequestMapping(path = StarshipControllerV2.PATH, produces = APPLICATION_JSON_VALUE)
@ApiGuideline(ApiGuidelineVersion.V2)
@ApiValidated(status = HttpStatus.BAD_GATEWAY, value = "StarshipCreateConstraintException")
public class StarshipControllerV2 {

public static final String PATH = "api/v2/starship";

@PostMapping(path = "/create")
@ResponseStatus(code = HttpStatus.CREATED)
public String createStarship2(@RequestBody @ApiValid Starship dto) {
return "{\"starship\":\"created\"}";
}

@PostMapping(path = "/exception")
public Starship exceptionStarship2(@RequestBody @ApiValid Starship dto) {
throw new RuntimeException();
}



}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.tjf.sample.github.apicore.exception;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
Expand All @@ -19,6 +20,7 @@
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.web.servlet.MockMvc;
Expand All @@ -42,6 +44,15 @@ public void createStarshipWithoutExcpetionTest() throws Exception {
.andExpect(status().isCreated()).andExpect(content().json(expectedResult));
}

@Test
public void createStarshipWithoutExcpetionV2Test() throws Exception {
String expectedResult = "{\"starship\":\"created\"}";

mockMvc.perform(post("/api/v2/starship/create").contentType(MediaType.APPLICATION_JSON)
.content("{\"name\":\"Millenium Falcon\",\"description\":\"Nave do Han\",\"crew\":5}"))
.andExpect(status().isCreated()).andExpect(content().json(expectedResult));
}

@Test
public void createStarshipWithExceptionTest() throws JSONException, URISyntaxException {
String expectedResult = "{\"code\":\"StarshipCreateConstraintException\",\"message\":\"It's a trap\",\"detailedMessage\":\"The force is not with you\",\"type\":\"error\",\"details\":[{\"code\":\"Starship.description.Size\",\"message\":\"Ship description must not be less than 1 or greater than 15\",\"detailedMessage\":\"description: A sucata mais veloz da galaxia\"}]}";
Expand All @@ -59,4 +70,38 @@ public void createStarshipWithExceptionTest() throws JSONException, URISyntaxExc
assertEquals(expectedResult, result.getBody());
}

@Test
public void createStarshipWithExceptionV2Test() throws JSONException, URISyntaxException {
String expectedResult = "{\"code\":\"StarshipCreateConstraintException\",\"message\":\"It's a trap\",\"detailedMessage\":\"The force is not with you\",\"type\":\"error\",\"details\":[{\"code\":\"Starship.description.Size\",\"message\":\"Ship description must not be less than 1 or greater than 15\",\"detailedMessage\":\"description: A sucata mais veloz da galaxia\"}]}";
URI uri = new URI("/api/v2/starship/create");

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAcceptLanguageAsLocales(List.of(Locale.forLanguageTag("en-US")));

HttpEntity<String> entity = new HttpEntity<String>(
"{\"name\":\"Millenium Falcon\",\"description\":\"A sucata mais veloz da galaxia\",\"crew\":5}",
headers);
ResponseEntity<String> result = template.postForEntity(uri, entity, String.class);

assertEquals(expectedResult, result.getBody());
}

@Test
public void createStarshipWithThrowV2Test() throws JSONException, URISyntaxException {
String expectedResult = "{\"code\":\"RuntimeException\",\"message\":\"Unmapped error, see stackTrace in details\",\"detailedMessage\"";
URI uri = new URI("/api/v2/starship/exception");

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAcceptLanguageAsLocales(List.of(Locale.forLanguageTag("en-US")));

HttpEntity<String> entity = new HttpEntity<String>(
"{\"name\":\"Millenium Falcon\",\"description\":\"A galaxia\",\"crew\":5}",
headers);
ResponseEntity<String> result = template.postForEntity(uri, entity, String.class);

assertTrue(result.getBody().contains(expectedResult));
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, result.getStatusCode());
}
}