View Javadoc
1   package de.aikiit.bilanzanalyser.upload;
2   
3   import de.aikiit.bilanzanalyser.entity.BilanzRow;
4   import de.aikiit.bilanzanalyser.entity.database.BilanzRowEntity;
5   import de.aikiit.bilanzanalyser.entity.database.CategoryEntity;
6   import de.aikiit.bilanzanalyser.entity.database.PaymentEntity;
7   import de.aikiit.bilanzanalyser.entity.database.ShopEntity;
8   import de.aikiit.bilanzanalyser.entity.database.SourceEntity;
9   import de.aikiit.bilanzanalyser.entity.database.repository.BilanzRowRepository;
10  import de.aikiit.bilanzanalyser.entity.database.repository.CategoryRepository;
11  import de.aikiit.bilanzanalyser.entity.database.repository.PaymentRepository;
12  import de.aikiit.bilanzanalyser.entity.database.repository.ShopRepository;
13  import de.aikiit.bilanzanalyser.entity.database.repository.SourceRepository;
14  import de.aikiit.bilanzanalyser.reader.BilanzRowParserResult;
15  import org.junit.jupiter.api.Test;
16  import org.junit.jupiter.api.extension.ExtendWith;
17  import org.mockito.InjectMocks;
18  import org.mockito.Mock;
19  import org.mockito.junit.jupiter.MockitoExtension;
20  import org.springframework.dao.DataIntegrityViolationException;
21  
22  import java.math.BigDecimal;
23  import java.time.LocalDate;
24  import java.util.List;
25  import java.util.Optional;
26  
27  import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
28  import static org.mockito.ArgumentMatchers.any;
29  import static org.mockito.Mockito.mock;
30  import static org.mockito.Mockito.times;
31  import static org.mockito.Mockito.verify;
32  import static org.mockito.Mockito.when;
33  
34  @ExtendWith(MockitoExtension.class)
35  class UploadAnalysisServiceTest {
36  
37      @Mock
38      private BilanzRowRepository bilanzRowRepository;
39      @Mock
40      private ShopRepository shopRepository;
41      @Mock
42      private PaymentRepository paymentRepository;
43      @Mock
44      private CategoryRepository categoryRepository;
45      @Mock
46      private SourceRepository sourceRepository;
47  
48      @InjectMocks
49      private UploadAnalysisService service;
50  
51      @Test
52      void getOrCreatePayment_shouldHandleConcurrentInsert() {
53          when(paymentRepository.findByName("Cards")).thenReturn(Optional.empty())  // first call
54                  .thenReturn(Optional.of(new PaymentEntity())); // retry
55  
56          when(paymentRepository.save(any())).thenThrow(DataIntegrityViolationException.class);
57  
58          PaymentEntity result = service.getOrCreatePayment("Cards");
59  
60          assertThat(result).isNotNull();
61          // called twice due to concurrent insert
62          verify(paymentRepository, times(2)).findByName("Cards");
63      }
64  
65      @Test
66      void replaceIfEmpty_shouldReplaceNullAndBlank() {
67          assertThat(service.replaceIfEmpty(null)).isEqualTo("<empty>");
68          assertThat(service.replaceIfEmpty(" ")).isEqualTo("<empty>");
69          assertThat(service.replaceIfEmpty("   value  ")).isEqualTo("value");
70      }
71  
72      @Test
73      void flushDataIntoDatabase_shouldSaveRows() {
74          BilanzRow row = mock(BilanzRow.class);
75          when(row.getDate()).thenReturn(LocalDate.now());
76          when(row.getAmount()).thenReturn(BigDecimal.TEN);
77          when(row.getDescription()).thenReturn("desc");
78          when(row.getShop()).thenReturn("shop");
79          when(row.getPayment()).thenReturn("cash");
80          when(row.getCategory()).thenReturn("food");
81          when(row.getSource()).thenReturn("app");
82  
83          BilanzRowParserResult result = mock(BilanzRowParserResult.class);
84          when(result.rows()).thenReturn(List.of(row));
85  
86          when(shopRepository.findByName(any())).thenReturn(Optional.of(new ShopEntity()));
87          when(paymentRepository.findByName(any())).thenReturn(Optional.of(new PaymentEntity()));
88          when(categoryRepository.findByName(any())).thenReturn(Optional.of(new CategoryEntity()));
89          when(sourceRepository.findByName(any())).thenReturn(Optional.of(new SourceEntity()));
90  
91          service.flushDataIntoDatabase(result);
92  
93          verify(bilanzRowRepository).save(any(BilanzRowEntity.class));
94      }
95  }