package com.fosspowered.peist.service; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import com.fosspowered.peist.model.dao.Paste; import com.fosspowered.peist.model.exceptions.PeistInvalidRequestException; import com.fosspowered.peist.model.exceptions.PeistNotFoundException; import com.fosspowered.peist.model.json.PasteRequest; import com.fosspowered.peist.model.json.PasteResponse; import com.fosspowered.peist.repository.PasteRepository; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Optional; import org.apache.commons.lang3.RandomStringUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.NullAndEmptySource; import org.mockito.Mockito; import org.mockito.stubbing.Answer; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.junit.jupiter.SpringExtension; @ExtendWith(SpringExtension.class) class CRUDServiceTest { private static final String INVALID_ID = "invalidId"; @MockBean private PasteRepository pasteRepository; private CRUDService CRUDService; @BeforeEach void setUp() { CRUDService = new CRUDService(pasteRepository, "password"); when(pasteRepository.findByUrlId(anyString())) .thenAnswer( (Answer>) invocationOnMock -> { Object[] args = invocationOnMock.getArguments(); String urlId = (String) args[0]; if (INVALID_ID.equals(urlId)) { return Optional.empty(); } Paste paste = new Paste(); paste.setUrlId(urlId); return Optional.of(paste); }); when(pasteRepository.findAll()).thenReturn(List.of(new Paste(), new Paste(), new Paste())); when(pasteRepository.save(Mockito.any(Paste.class))).thenReturn(new Paste()); } @Test void whenAddPaste_ValidRequest_SavesPaste() { String author = "author"; String language = "language"; String title = "title"; int ttl = 3600; Calendar calendar = Calendar.getInstance(); Date currentDate = new Date(calendar.getTime().getTime()); calendar.add(Calendar.SECOND, ttl); Date expiryDate = new Date(calendar.getTime().getTime()); String pasteData = RandomStringUtils.randomAlphabetic(100); PasteRequest pasteRequest = PasteRequest.builder() .title(title) .language(language) .author(author) .secretKey(null) .ttl(ttl) .pasteData(pasteData) .build(); PasteResponse pasteResponse = CRUDService.addPaste(pasteRequest); verify(pasteRepository, times(1)).save(any(Paste.class)); assertThat(pasteResponse).isNotNull(); assertThat(pasteResponse.getUrlId()).isNotEmpty(); assertThat(pasteResponse.getTitle()).isEqualTo(title); assertThat(pasteResponse.getAuthor()).isEqualTo(author); assertThat(pasteResponse.getCreationDate()).isCloseTo(currentDate, 60); assertThat(pasteResponse.getExpiryDate()).isCloseTo(expiryDate, 60); assertThat(pasteResponse.getPasteData()).isNotEmpty().isEqualTo(pasteData); } @Test void whenFetchPaste_ExistingId_ReturnsPaste() { PasteResponse pasteResponse = CRUDService.fetchPaste("id"); assertThat(pasteResponse).isNotNull(); } @Test void whenFetchPaste_NonExistingId_ThrowsException() { assertThrows(PeistNotFoundException.class, () -> CRUDService.fetchPaste(INVALID_ID)); } @ParameterizedTest(name = "run #{index} with [{arguments}]") @NullAndEmptySource void whenFetchPaste_InvalidId_ThrowsException(String id) { assertThrows(PeistInvalidRequestException.class, () -> CRUDService.fetchPaste(id)); } @Test void whenFetchRecentPastes_Any_RetrievesAll() { List pasteResponses = CRUDService.fetchRecentPastes(); assertThat(pasteResponses).isNotEmpty(); assertThat(pasteResponses).hasSize(3); } }