diff --git a/backend/src/main/java/com/github/binpastes/paste/api/PasteController.java b/backend/src/main/java/com/github/binpastes/paste/api/PasteController.java index 69c37a1..c0a5c39 100644 --- a/backend/src/main/java/com/github/binpastes/paste/api/PasteController.java +++ b/backend/src/main/java/com/github/binpastes/paste/api/PasteController.java @@ -87,14 +87,15 @@ public Mono findPastes() { public Mono searchPastes( @RequestParam("term") @NotBlank - @Pattern(regexp = "[\\pL\\pN\\p{P}\\s]{3,25}") + @Pattern(regexp = "[\\p{L}\\p{N}\\p{P}\\s]{3,50}") final String term, final ServerHttpResponse response ) { - response.getHeaders().setCacheControl(CacheControl.maxAge(60, TimeUnit.SECONDS)); + var decodedTerm = URLDecoder.decode(term, Charset.defaultCharset()); + response.getHeaders().setCacheControl(CacheControl.maxAge(1, TimeUnit.MINUTES)); return pasteService - .findByFullText(URLDecoder.decode(term, Charset.defaultCharset())) - .map(paste -> SearchItemView.of(paste, term)) + .findByFullText(decodedTerm) + .map(paste -> SearchItemView.of(paste, decodedTerm)) .collectList() .map(SearchView::of); } @@ -123,7 +124,7 @@ public void deletePaste(@PathVariable("pasteId") String pasteId, ServerHttpReque @ExceptionHandler({ConstraintViolationException.class, WebExchangeBindException.class}) @ResponseStatus(HttpStatus.BAD_REQUEST) private void handleValidationException(RuntimeException e) { - log.info("Received invalid request: {}", e.getClass().getSimpleName()); + log.info("Received invalid request [{}]: {}", e.getClass().getSimpleName(), e.getMessage()); } private static String remoteAddress(ServerHttpRequest request) { diff --git a/backend/src/test/java/com/github/binpastes/paste/api/PasteControllerTest.java b/backend/src/test/java/com/github/binpastes/paste/api/PasteControllerTest.java index 531ddcd..b39c4c1 100644 --- a/backend/src/test/java/com/github/binpastes/paste/api/PasteControllerTest.java +++ b/backend/src/test/java/com/github/binpastes/paste/api/PasteControllerTest.java @@ -58,24 +58,12 @@ void listPastes() { .uri("/api/v1/paste") .exchange() .expectStatus().isOk() + .expectHeader().cacheControl(CacheControl.empty()) .expectBody().jsonPath("pastes", emptyList()); } @Test - @DisplayName("GET /search - set cache header") - void searchPastes() { - doReturn(Flux.empty()).when(pasteService).findByFullText(anyString()); - - webClient.get() - .uri("/api/v1/paste/search?term={term}", "foobar") - .exchange() - .expectStatus().isOk() - .expectHeader().cacheControl(CacheControl.maxAge(1, TimeUnit.MINUTES)) - .expectBody().jsonPath("pastes", emptyList()); - } - - @Test - @DisplayName("GET /search - decode term parameter") + @DisplayName("GET /search - term parameter and cache header") void searchPastesDecodesParameter() { doReturn(Flux.empty()).when(pasteService).findByFullText(anyString()); @@ -121,7 +109,12 @@ private static Stream invalidPayloads() { "content": "validContent", } """))), - arguments(named("title too long", Mono.just("{\"content\": \"validContent\", \"title\": " + "X".repeat(256 + 1) + "\"}"))), + arguments(named("title too long", Mono.just(""" + { + "title": "%s", + "content": "validContent", + } + """.formatted("X".repeat(256 + 1))))), arguments(named("content blank", Mono.just(""" { "content": " ", @@ -132,7 +125,11 @@ private static Stream invalidPayloads() { "content": "1234", } """))), - arguments(named("content too long", Mono.just("{\"content\": \"" + "X".repeat(4096 + 1) + "\"}"))) + arguments(named("content too long", Mono.just(""" + { + "content": "%s", + } + """.formatted("X".repeat(4096 + 1))))) ); } }