-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add tests to Paste domain object and controller
- Loading branch information
Stefan Wilke
committed
Nov 13, 2023
1 parent
f68cda2
commit b325139
Showing
12 changed files
with
287 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
backend/src/main/java/com/github/binpastes/config/DatabaseConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.github.binpastes.config; | ||
|
||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.data.r2dbc.config.EnableR2dbcAuditing; | ||
import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories; | ||
|
||
@Configuration | ||
@EnableR2dbcRepositories | ||
@EnableR2dbcAuditing | ||
public class DatabaseConfig {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,6 @@ | |
class BinPastesTests { | ||
|
||
@Test | ||
void contextLoads() { | ||
} | ||
void contextLoads() {} | ||
|
||
} |
122 changes: 122 additions & 0 deletions
122
backend/src/test/java/com/github/binpastes/paste/api/PasteControllerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
package com.github.binpastes.paste.api; | ||
|
||
import com.github.binpastes.paste.domain.PasteService; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.Arguments; | ||
import org.junit.jupiter.params.provider.MethodSource; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; | ||
import org.springframework.boot.test.mock.mockito.MockBean; | ||
import org.springframework.http.CacheControl; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.test.web.reactive.server.WebTestClient; | ||
import reactor.core.publisher.Flux; | ||
import reactor.core.publisher.Mono; | ||
|
||
import java.util.concurrent.TimeUnit; | ||
import java.util.stream.Stream; | ||
|
||
import static java.util.Collections.emptyList; | ||
import static org.junit.jupiter.api.Named.named; | ||
import static org.junit.jupiter.params.provider.Arguments.arguments; | ||
import static org.mockito.ArgumentMatchers.anyString; | ||
import static org.mockito.Mockito.doReturn; | ||
|
||
@WebFluxTest | ||
class PasteControllerTest { | ||
|
||
@Autowired | ||
private WebTestClient webClient; | ||
|
||
@MockBean | ||
private PasteService pasteService; | ||
|
||
private static final String somePasteId = "4711471147114711471147114711471147114711"; | ||
|
||
@Test | ||
@DisplayName("GET /{pasteId} - 404 on unknown paste, no caching") | ||
void findUnknownPaste() { | ||
doReturn(Mono.empty()).when(pasteService).find(anyString()); | ||
|
||
webClient.get() | ||
.uri("/api/v1/paste/" + somePasteId) | ||
.exchange() | ||
.expectStatus().isNotFound() | ||
.expectHeader().doesNotExist(HttpHeaders.CACHE_CONTROL); | ||
} | ||
|
||
@Test | ||
@DisplayName("GET / - empty list on no results") | ||
void listPastes() { | ||
doReturn(Flux.empty()).when(pasteService).findAll(); | ||
|
||
webClient.get() | ||
.uri("/api/v1/paste") | ||
.exchange() | ||
.expectStatus().isOk() | ||
.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(60, TimeUnit.SECONDS)) | ||
.expectBody().jsonPath("pastes", emptyList()); | ||
} | ||
|
||
@Test | ||
@DisplayName("DELETE /{pasteId} - always return 204") | ||
void deletePaste() { | ||
webClient.delete() | ||
.uri("/api/v1/paste/" + somePasteId) | ||
.exchange() | ||
.expectStatus().isNoContent() | ||
.expectBody().isEmpty(); | ||
} | ||
|
||
@ParameterizedTest | ||
@DisplayName("POST / - 400 on invalid input") | ||
@MethodSource("invalidPayloads") | ||
void createPaste(Mono<String> payload) { | ||
webClient.post() | ||
.uri("/api/v1/paste") | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.body(payload, String.class) | ||
.exchange() | ||
.expectStatus().isBadRequest() | ||
.expectBody().consumeWith(System.out::println); | ||
} | ||
|
||
private static Stream<Arguments> invalidPayloads() { | ||
return Stream.of( | ||
arguments(named("body is null", Mono.empty())), | ||
arguments(named("body blank", Mono.just(""))), | ||
arguments(named("title too long", Mono.just(""" | ||
{ | ||
"title": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", | ||
"content": "validContent" | ||
} | ||
"""))), | ||
arguments(named("content blank", Mono.just(""" | ||
{ | ||
"content": " ", | ||
} | ||
"""))), | ||
arguments(named("content too short", Mono.just(""" | ||
{ | ||
"content": "1234", | ||
} | ||
"""))), | ||
arguments(named("content too long", Mono.just("{\"content\": \"" + "X".repeat(4096 + 1) + "\"}"))) | ||
); | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
backend/src/test/java/com/github/binpastes/paste/api/model/SearchItemViewTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.github.binpastes.paste.api.model; | ||
|
||
import com.github.binpastes.paste.api.model.SearchView.SearchItemView; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.CsvSource; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
class SearchItemViewTest { | ||
|
||
private static final String content = """ | ||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur egestas odio faucibus mi commodo faucibus. Mauris pellentesque vitae urna sed vehicula. Mauris sollicitudin rutrum condimentum. Sed vel cursus neque, vel imperdiet justo. Integer et volutpat erat, at ullamcorper nisi. Praesent viverra interdum ex, eget scelerisque augue. Nunc sagittis libero quis tristique rutrum. Vestibulum dapibus ex vel auctor mattis. Donec vel vulputate sem, at posuere magna. Curabitur sodales condimentum erat, et pellentesque est viverra quis. | ||
""".trim(); | ||
|
||
@ParameterizedTest | ||
@DisplayName("highlight - extract excerpt from content") | ||
@CsvSource(delimiter = '|', textBlock = """ | ||
'elit' | 'amet, consectetur adipiscing elit. Curabitur egestas odio fauci' | ||
'foobar' | 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cur' | ||
""") | ||
void highlight(String term, String expectedHighlight) { | ||
|
||
assertThat(SearchItemView.highlight(content, term)).isEqualTo(expectedHighlight); | ||
|
||
} | ||
} |
106 changes: 106 additions & 0 deletions
106
backend/src/test/java/com/github/binpastes/paste/domain/PasteTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package com.github.binpastes.paste.domain; | ||
|
||
import com.github.binpastes.paste.domain.Paste.PasteExposure; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.Arguments; | ||
import org.junit.jupiter.params.provider.MethodSource; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.stream.Stream; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.junit.jupiter.api.Assertions.assertThrows; | ||
import static org.junit.jupiter.params.provider.Arguments.arguments; | ||
|
||
class PasteTest { | ||
|
||
@Test | ||
@DisplayName("new paste - requires mandatory fields") | ||
void newInstanceMandatoryFields() { | ||
assertThrows( | ||
NullPointerException.class, | ||
() -> Paste.newInstance(null, null, null, false, PasteExposure.PUBLIC, null), | ||
"content is mandatory" | ||
); | ||
|
||
assertThrows( | ||
NullPointerException.class, | ||
() -> Paste.newInstance(null, "someContent", null, false, null, null), | ||
"exposure is mandatory" | ||
); | ||
} | ||
|
||
@Test | ||
@DisplayName("new paste - sets defaults") | ||
void newInstanceDefaults() { | ||
var newPaste = Paste.newInstance(null, "someContent", null, false, PasteExposure.PUBLIC, null); | ||
|
||
assertThat(newPaste.getId()).isNotEmpty(); | ||
assertThat(newPaste.getViews()).isZero(); | ||
assertThat(newPaste.getLastViewed()).isNull(); | ||
|
||
assertThat(newPaste.getTitle()).isNull(); | ||
assertThat(newPaste.getContent()).isEqualTo("someContent"); | ||
assertThat(newPaste.isPermanent()).isTrue(); | ||
assertThat(newPaste.isEncrypted()).isFalse(); | ||
assertThat(newPaste.isPublic()).isTrue(); | ||
assertThat(newPaste.getRemoteAddress()).isNull(); | ||
} | ||
|
||
@Test | ||
@DisplayName("track paste - increases view count") | ||
void trackPasteViewCount() { | ||
var newPaste = Paste.newInstance(null, "someContent", null, false, PasteExposure.PUBLIC, null); | ||
|
||
newPaste.trackView(LocalDateTime.now()); | ||
newPaste.trackView(LocalDateTime.now()); | ||
|
||
assertThat(newPaste.getViews()).isEqualTo(2); | ||
} | ||
|
||
@Test | ||
@DisplayName("track paste - updates lastViewed timestamp to most recent one") | ||
void trackPasteLastViewed() { | ||
var newPaste = Paste.newInstance(null, "someContent", null, false, PasteExposure.PUBLIC, null); | ||
var now = LocalDateTime.now(); | ||
var yesterday = LocalDateTime.now().minusDays(1); | ||
|
||
newPaste.trackView(now); | ||
newPaste.trackView(yesterday); | ||
|
||
assertThat(newPaste.getLastViewed()).isEqualTo(now); | ||
assertThat(newPaste.getViews()).isEqualTo(2); | ||
} | ||
|
||
@ParameterizedTest | ||
@DisplayName("erase paste - allowed only under certain conditions") | ||
@MethodSource("pastesToErase") | ||
void isErasable(Paste paste, String requestedBy, boolean erasable) { | ||
assertThat(paste.isErasable(requestedBy)) | ||
.isEqualTo(erasable); | ||
} | ||
|
||
private static Stream<Arguments> pastesToErase() { | ||
var unlistedPaste = Paste.newInstance(null, "someContent", null, false, PasteExposure.UNLISTED, "Alice"); | ||
var oneTimePaste = Paste.newInstance(null, "someContent", null, false, PasteExposure.ONCE, "Alice"); | ||
|
||
var publicPasteRecentlyCreatedByAlice = Paste.newInstance(null, "someContent", null, false, PasteExposure.PUBLIC, "Alice"); | ||
publicPasteRecentlyCreatedByAlice.setDateCreated(LocalDateTime.now().minusMinutes(59)); | ||
|
||
var publicPasteCreatedSomeTimeAgoByAlice = Paste.newInstance(null, "someContent", null, false, PasteExposure.PUBLIC, "Alice"); | ||
publicPasteCreatedSomeTimeAgoByAlice.setDateCreated(LocalDateTime.now().minusMinutes(60)); | ||
|
||
return Stream.of( | ||
arguments(unlistedPaste, null, true), | ||
arguments(oneTimePaste, null, true), | ||
|
||
arguments(publicPasteRecentlyCreatedByAlice, "Alice", true), | ||
arguments(publicPasteRecentlyCreatedByAlice, "Bob", false), | ||
|
||
arguments(publicPasteCreatedSomeTimeAgoByAlice, "Alice", false), | ||
arguments(publicPasteCreatedSomeTimeAgoByAlice, "Bob", false) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters