From 65dc190f176a2d0140b7a530dc249c2975f595f1 Mon Sep 17 00:00:00 2001
From: Robert Goldmann <deadlocker@gmx.de>
Date: Fri, 22 Jul 2022 23:00:46 +0200
Subject: [PATCH] #677 - added keyword service

---
 .../TransactionNameKeywordService.java        | 64 +++++++++++++
 .../TransactionNameKeywordServiceTest.java    | 94 +++++++++++++++++++
 2 files changed, 158 insertions(+)
 create mode 100644 BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/keywords/TransactionNameKeywordService.java
 create mode 100644 BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/TransactionNameKeywordServiceTest.java

diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/keywords/TransactionNameKeywordService.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/keywords/TransactionNameKeywordService.java
new file mode 100644
index 000000000..8718acecf
--- /dev/null
+++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/keywords/TransactionNameKeywordService.java
@@ -0,0 +1,64 @@
+package de.deadlocker8.budgetmaster.transactions.keywords;
+
+import de.deadlocker8.budgetmaster.services.Resettable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Locale;
+
+@Service
+public class TransactionNameKeywordService implements Resettable
+{
+	private static final Logger LOGGER = LoggerFactory.getLogger(TransactionNameKeywordService.class);
+	private static final List<String> DEFAULT_KEYWORDS = List.of("income", "einnahme");
+
+	private final TransactionNameKeywordRepository transactionNameKeywordRepository;
+
+
+	@Autowired
+	public TransactionNameKeywordService(TransactionNameKeywordRepository transactionNameKeywordRepository)
+	{
+		this.transactionNameKeywordRepository = transactionNameKeywordRepository;
+
+		createDefaults();
+	}
+
+	public TransactionNameKeywordRepository getRepository()
+	{
+		return transactionNameKeywordRepository;
+	}
+
+	@Override
+	public void deleteAll()
+	{
+		LOGGER.info("Resetting transaction name keywords...");
+		transactionNameKeywordRepository.deleteAll();
+		LOGGER.info("All transaction name keywords reset.");
+	}
+
+	@Override
+	public void createDefaults()
+	{
+		if(transactionNameKeywordRepository.findAll().isEmpty())
+		{
+			for(String keyword : DEFAULT_KEYWORDS)
+			{
+				transactionNameKeywordRepository.save(new TransactionNameKeyword(keyword));
+			}
+		}
+	}
+
+	public List<String> getMatchingKeywords(String text)
+	{
+		final List<TransactionNameKeyword> keywords = transactionNameKeywordRepository.findAll();
+		final String textLowerCase = text.toLowerCase();
+
+		return keywords.stream()
+				.map(TransactionNameKeyword::getValue)
+				.filter(value -> textLowerCase.contains(value.toLowerCase(Locale.ROOT)))
+				.toList();
+	}
+}
diff --git a/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/TransactionNameKeywordServiceTest.java b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/TransactionNameKeywordServiceTest.java
new file mode 100644
index 000000000..48d93c924
--- /dev/null
+++ b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/TransactionNameKeywordServiceTest.java
@@ -0,0 +1,94 @@
+package de.deadlocker8.budgetmaster.unit;
+
+import de.deadlocker8.budgetmaster.transactions.keywords.TransactionNameKeyword;
+import de.deadlocker8.budgetmaster.transactions.keywords.TransactionNameKeywordRepository;
+import de.deadlocker8.budgetmaster.transactions.keywords.TransactionNameKeywordService;
+import de.deadlocker8.budgetmaster.unit.helpers.LocalizedTest;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@ExtendWith(SpringExtension.class)
+@LocalizedTest
+class TransactionNameKeywordServiceTest
+{
+	private static final TransactionNameKeyword KEYWORD_1 = new TransactionNameKeyword("income");
+	private static final TransactionNameKeyword KEYWORD_2 = new TransactionNameKeyword("abc");
+
+	@Mock
+	private TransactionNameKeywordRepository transactionNameKeywordRepository;
+
+	@InjectMocks
+	private TransactionNameKeywordService transactionNameKeywordService;
+
+	@Test
+	void test_getMatchingKeywords_emptyString()
+	{
+		Mockito.when(transactionNameKeywordRepository.findAll()).thenReturn(List.of(KEYWORD_1, KEYWORD_2));
+
+		final List<String> matchingKeywords = transactionNameKeywordService.getMatchingKeywords("");
+
+		assertThat(matchingKeywords).isEmpty();
+	}
+
+	@Test
+	void test_getMatchingKeywords_noMatch()
+	{
+		Mockito.when(transactionNameKeywordRepository.findAll()).thenReturn(List.of(KEYWORD_1, KEYWORD_2));
+
+		final List<String> matchingKeywords = transactionNameKeywordService.getMatchingKeywords("0815");
+
+		assertThat(matchingKeywords).isEmpty();
+	}
+
+	@Test
+	void test_getMatchingKeywords_matchFirstKeyword()
+	{
+		Mockito.when(transactionNameKeywordRepository.findAll()).thenReturn(List.of(KEYWORD_1, KEYWORD_2));
+
+		final List<String> matchingKeywords = transactionNameKeywordService.getMatchingKeywords("income");
+
+		assertThat(matchingKeywords)
+				.containsExactly(KEYWORD_1.getValue());
+	}
+
+	@Test
+	void test_getMatchingKeywords_matchAnotherKeyword()
+	{
+		Mockito.when(transactionNameKeywordRepository.findAll()).thenReturn(List.of(KEYWORD_1, KEYWORD_2));
+
+		final List<String> matchingKeywords = transactionNameKeywordService.getMatchingKeywords("Lorem ipsum abc sadsad");
+
+		assertThat(matchingKeywords)
+				.containsExactly(KEYWORD_2.getValue());
+	}
+
+	@Test
+	void test_getMatchingKeywords_matchMultipleKeywords()
+	{
+		Mockito.when(transactionNameKeywordRepository.findAll()).thenReturn(List.of(KEYWORD_1, KEYWORD_2));
+
+		final List<String> matchingKeywords = transactionNameKeywordService.getMatchingKeywords("abcincome");
+
+		assertThat(matchingKeywords)
+				.containsExactly(KEYWORD_1.getValue(), KEYWORD_2.getValue());
+	}
+
+	@Test
+	void test_getMatchingKeywords_ignoreCase()
+	{
+		Mockito.when(transactionNameKeywordRepository.findAll()).thenReturn(List.of(KEYWORD_1, KEYWORD_2));
+
+		final List<String> matchingKeywords = transactionNameKeywordService.getMatchingKeywords("asdsad InCoMEasdasdsad");
+
+		assertThat(matchingKeywords)
+				.containsExactly(KEYWORD_1.getValue());
+	}
+}
-- 
GitLab