From 126d9abf6b3561d928a222463be653ea61f98520 Mon Sep 17 00:00:00 2001 From: mvvasilev Date: Sun, 14 Jan 2024 22:09:28 +0200 Subject: [PATCH] Tests maybe --- .../finances/services/CategoryService.java | 14 +- .../finances/CategorizationBuilder.java | 184 ++++++++++++++++++ .../finances/CategoryServiceTests.java | 33 ++++ .../services/CategoryServiceTest.java | 36 ++++ 4 files changed, 257 insertions(+), 10 deletions(-) create mode 100644 PersonalFinancesService/src/test/java/dev/mvvasilev/finances/CategorizationBuilder.java create mode 100644 PersonalFinancesService/src/test/java/dev/mvvasilev/finances/CategoryServiceTests.java create mode 100644 PersonalFinancesService/src/test/java/dev/mvvasilev/finances/services/CategoryServiceTest.java diff --git a/PersonalFinancesService/src/main/java/dev/mvvasilev/finances/services/CategoryService.java b/PersonalFinancesService/src/main/java/dev/mvvasilev/finances/services/CategoryService.java index 2fa5686..799fb22 100644 --- a/PersonalFinancesService/src/main/java/dev/mvvasilev/finances/services/CategoryService.java +++ b/PersonalFinancesService/src/main/java/dev/mvvasilev/finances/services/CategoryService.java @@ -82,7 +82,7 @@ public class CategoryService { processedTransactionCategoryRepository.deleteAllForTransactions(transactions.stream().map(AbstractEntity::getId).toList()); - // Run each category's rules for all transactions in parallel to eachother + // Run each category's rules for all transactions concurrently to each other final var futures = categorizations.stream() .filter(Categorization::isRoot) .collect(Collectors.groupingBy(Categorization::getCategoryId, HashMap::new, Collectors.toList())) @@ -118,7 +118,7 @@ public class CategoryService { })) .toArray(length -> (CompletableFuture>[]) new CompletableFuture[length]); - // Run them all in parallel + // Run them all concurrently/in parallel final var ptcs = CompletableFuture.allOf(futures).thenApply((v) -> Arrays.stream(futures) .flatMap(future -> future.join().stream()) @@ -128,15 +128,9 @@ public class CategoryService { processedTransactionCategoryRepository.saveAllAndFlush(ptcs); } - private Optional categorizeTransaction(final Collection allCategorizations, Categorization categorization, ProcessedTransaction processedTransaction) { - if (matchesRule(allCategorizations, categorization, processedTransaction)) { - return Optional.of(new ProcessedTransactionCategory(processedTransaction.getId(), categorization.getCategoryId())); - } else { - return Optional.empty(); - } - } - private boolean matchesRule(final Collection allCategorizations, final Categorization categorization, final ProcessedTransaction processedTransaction) { + + public boolean matchesRule(final Collection allCategorizations, final Categorization categorization, final ProcessedTransaction processedTransaction) { return switch (categorization.getCategorizationRule()) { // string operations case STRING_REGEX, STRING_EQ, STRING_CONTAINS, STRING_IS_EMPTY -> { diff --git a/PersonalFinancesService/src/test/java/dev/mvvasilev/finances/CategorizationBuilder.java b/PersonalFinancesService/src/test/java/dev/mvvasilev/finances/CategorizationBuilder.java new file mode 100644 index 0000000..45b08cd --- /dev/null +++ b/PersonalFinancesService/src/test/java/dev/mvvasilev/finances/CategorizationBuilder.java @@ -0,0 +1,184 @@ +package dev.mvvasilev.finances; + +import dev.mvvasilev.finances.entity.Categorization; +import dev.mvvasilev.finances.enums.CategorizationRule; +import dev.mvvasilev.finances.enums.ProcessedTransactionField; +import org.apache.commons.lang3.RandomUtils; + +import java.time.LocalDateTime; + +public class CategorizationBuilder { + + private Categorization categorization; + + public CategorizationBuilder() {} + + private CategorizationBuilder(Categorization categorization) { + this.categorization = categorization; + } + + public static CategorizationBuilder withUser(int userId) { + var categorization = new Categorization(); + + categorization.setUserId(userId); + + return new CategorizationBuilder(categorization); + } + + public static CategorizationBuilder withCategory(long categoryId) { + var categorization = new Categorization(); + + categorization.setCategoryId(categoryId); + + return new CategorizationBuilder(categorization); + } + + public static CategorizationBuilder onField(ProcessedTransactionField field, CategorizationRule rule, boolean booleanValue) { + var categorization = new Categorization(); + + categorization.setRuleBasedOn(field); + categorization.setCategorizationRule(rule); + categorization.setBooleanValue(booleanValue); + + return new CategorizationBuilder(categorization); + } + + public static CategorizationBuilder onField(ProcessedTransactionField field, CategorizationRule rule, double numericValue) { + var categorization = new Categorization(); + + categorization.setRuleBasedOn(field); + categorization.setCategorizationRule(rule); + categorization.setNumericValue(numericValue); + + return new CategorizationBuilder(categorization); + } + + public static CategorizationBuilder onField(ProcessedTransactionField field, CategorizationRule rule, String stringValue) { + var categorization = new Categorization(); + + categorization.setRuleBasedOn(field); + categorization.setCategorizationRule(rule); + categorization.setStringValue(stringValue); + + return new CategorizationBuilder(categorization); + } + + public static CategorizationBuilder onBetween(ProcessedTransactionField field, double greaterThan, double lessThan) { + var categorization = new Categorization(); + + categorization.setRuleBasedOn(field); + categorization.setCategorizationRule(CategorizationRule.NUMERIC_BETWEEN); + categorization.setNumericGreaterThan(greaterThan); + categorization.setNumericLessThan(lessThan); + + return new CategorizationBuilder(categorization); + } + + public static CategorizationBuilder onBetween(ProcessedTransactionField field, LocalDateTime greaterThan, LocalDateTime lessThan) { + var categorization = new Categorization(); + + categorization.setRuleBasedOn(field); + categorization.setCategorizationRule(CategorizationRule.TIMESTAMP_BETWEEN); + categorization.setTimestampGreaterThan(greaterThan); + categorization.setTimestampLessThan(lessThan); + + return new CategorizationBuilder(categorization); + } + + public static CategorizationBuilder and(Categorization left, Categorization right) { + var categorization = new Categorization(); + + categorization.setCategorizationRule(CategorizationRule.AND); + categorization.setLeftCategorizationId(left.getId()); + categorization.setRightCategorizationId(right.getId()); + + return new CategorizationBuilder(categorization); + } + + public static CategorizationBuilder or(Categorization left, Categorization right) { + var categorization = new Categorization(); + + categorization.setCategorizationRule(CategorizationRule.OR); + categorization.setLeftCategorizationId(left.getId()); + categorization.setRightCategorizationId(right.getId()); + + return new CategorizationBuilder(categorization); + } + + public static CategorizationBuilder not(Categorization right) { + var categorization = new Categorization(); + + categorization.setCategorizationRule(CategorizationRule.NOT); + categorization.setRightCategorizationId(right.getId()); + + return new CategorizationBuilder(categorization); + } + + public CategorizationBuilder user(int userId) { + categorization.setUserId(userId); + + return this; + } + + public CategorizationBuilder category(long categoryId) { + categorization.setCategoryId(categoryId); + + return this; + } + + public CategorizationBuilder on(ProcessedTransactionField field, CategorizationRule rule, boolean booleanValue) { + categorization.setRuleBasedOn(field); + categorization.setCategorizationRule(rule); + categorization.setBooleanValue(booleanValue); + + return this; + } + + public CategorizationBuilder on(ProcessedTransactionField field, CategorizationRule rule, double numericValue) { + categorization.setRuleBasedOn(field); + categorization.setCategorizationRule(rule); + categorization.setNumericValue(numericValue); + + return this; + } + + public CategorizationBuilder on(ProcessedTransactionField field, CategorizationRule rule, String stringValue) { + categorization.setRuleBasedOn(field); + categorization.setCategorizationRule(rule); + categorization.setStringValue(stringValue); + + return this; + } + + public CategorizationBuilder between(ProcessedTransactionField field, double greaterThan, double lessThan) { + categorization.setRuleBasedOn(field); + categorization.setCategorizationRule(CategorizationRule.NUMERIC_BETWEEN); + categorization.setNumericGreaterThan(greaterThan); + categorization.setNumericLessThan(lessThan); + + return this; + } + + public CategorizationBuilder between(ProcessedTransactionField field, LocalDateTime greaterThan, LocalDateTime lessThan) { + categorization.setRuleBasedOn(field); + categorization.setCategorizationRule(CategorizationRule.TIMESTAMP_BETWEEN); + categorization.setTimestampGreaterThan(greaterThan); + categorization.setTimestampLessThan(lessThan); + + return this; + } + + public Categorization build(boolean isRoot) { + categorization.setId(RandomUtils.nextLong()); + categorization.setRoot(isRoot); + + return categorization; + } + + public Categorization build() { + categorization.setId(RandomUtils.nextLong()); + categorization.setRoot(false); + + return categorization; + } +} diff --git a/PersonalFinancesService/src/test/java/dev/mvvasilev/finances/CategoryServiceTests.java b/PersonalFinancesService/src/test/java/dev/mvvasilev/finances/CategoryServiceTests.java new file mode 100644 index 0000000..b58c523 --- /dev/null +++ b/PersonalFinancesService/src/test/java/dev/mvvasilev/finances/CategoryServiceTests.java @@ -0,0 +1,33 @@ +package dev.mvvasilev.finances; + +import dev.mvvasilev.finances.persistence.CategorizationRepository; +import dev.mvvasilev.finances.persistence.ProcessedTransactionCategoryRepository; +import dev.mvvasilev.finances.persistence.ProcessedTransactionRepository; +import dev.mvvasilev.finances.persistence.TransactionCategoryRepository; +import dev.mvvasilev.finances.services.CategoryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; + +@SpringBootTest +public class CategoryServiceTests { + + @MockBean + private TransactionCategoryRepository transactionCategoryRepository; + + @MockBean + private CategorizationRepository categorizationRepository; + + @MockBean + private ProcessedTransactionRepository processedTransactionRepository; + + @MockBean + private ProcessedTransactionCategoryRepository processedTransactionCategoryRepository; + + @Autowired + private CategoryService service; + + public CategoryServiceTests() { + } + +} diff --git a/PersonalFinancesService/src/test/java/dev/mvvasilev/finances/services/CategoryServiceTest.java b/PersonalFinancesService/src/test/java/dev/mvvasilev/finances/services/CategoryServiceTest.java new file mode 100644 index 0000000..b58c1dd --- /dev/null +++ b/PersonalFinancesService/src/test/java/dev/mvvasilev/finances/services/CategoryServiceTest.java @@ -0,0 +1,36 @@ +package dev.mvvasilev.finances.services; + +import dev.mvvasilev.finances.CategorizationBuilder; +import dev.mvvasilev.finances.persistence.CategorizationRepository; +import dev.mvvasilev.finances.persistence.ProcessedTransactionCategoryRepository; +import dev.mvvasilev.finances.persistence.ProcessedTransactionRepository; +import dev.mvvasilev.finances.persistence.TransactionCategoryRepository; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; + +import static org.junit.jupiter.api.Assertions.*; +@SpringBootTest +class CategoryServiceTest { + + @MockBean + private TransactionCategoryRepository transactionCategoryRepository; + + @MockBean + private CategorizationRepository categorizationRepository; + + @MockBean + private ProcessedTransactionRepository processedTransactionRepository; + + @MockBean + private ProcessedTransactionCategoryRepository processedTransactionCategoryRepository; + + @Autowired + private CategoryService service; + + @Test + void matchesRule() { + + } +} \ No newline at end of file