From 7c4dc74a8e05ce87b8a41e726bf6d07012a6ea1c Mon Sep 17 00:00:00 2001 From: Robert Goldmann <deadlocker@gmx.de> Date: Wed, 30 Mar 2022 21:56:12 +0200 Subject: [PATCH] #691 - importer for templates --- .../database/importer/TemplateImporter.java | 55 +++ .../importer/TransactionImporter.java | 3 +- .../budgetmaster/services/ImportService.java | 40 +-- .../importer/TemplateImporterTest.java | 316 ++++++++++++++++++ 4 files changed, 375 insertions(+), 39 deletions(-) create mode 100644 src/main/java/de/deadlocker8/budgetmaster/database/importer/TemplateImporter.java create mode 100644 src/test/java/de/deadlocker8/budgetmaster/unit/database/importer/TemplateImporterTest.java diff --git a/src/main/java/de/deadlocker8/budgetmaster/database/importer/TemplateImporter.java b/src/main/java/de/deadlocker8/budgetmaster/database/importer/TemplateImporter.java new file mode 100644 index 000000000..68da11b65 --- /dev/null +++ b/src/main/java/de/deadlocker8/budgetmaster/database/importer/TemplateImporter.java @@ -0,0 +1,55 @@ +package de.deadlocker8.budgetmaster.database.importer; + +import de.deadlocker8.budgetmaster.services.EntityType; +import de.deadlocker8.budgetmaster.templategroup.TemplateGroup; +import de.deadlocker8.budgetmaster.templates.Template; +import de.deadlocker8.budgetmaster.templates.TemplateRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.MessageFormat; + +public class TemplateImporter extends ItemImporter<Template> +{ + private static final Logger LOGGER = LoggerFactory.getLogger(TemplateImporter.class); + + private final TagImporter tagImporter; + private final TemplateGroup defaultTemplateGroup; + private final boolean alwaysAssignDefaultTemplateGroup; + + public TemplateImporter(TemplateRepository templateRepository, TagImporter tagImporter, TemplateGroup defaultTemplateGroup, boolean alwaysAssignDefaultTemplateGroup) + { + super(templateRepository, EntityType.TEMPLATE); + this.tagImporter = tagImporter; + this.defaultTemplateGroup = defaultTemplateGroup; + this.alwaysAssignDefaultTemplateGroup = alwaysAssignDefaultTemplateGroup; + } + + @Override + protected int importSingleItem(Template template) + { + if(!(repository instanceof TemplateRepository repository)) + { + throw new IllegalArgumentException("Invalid repository type"); + } + + LOGGER.debug(MessageFormat.format("Importing template with templateName: {0})", template.getTemplateName())); + + tagImporter.importItems(template.getTags()); + template.setID(null); + + if(alwaysAssignDefaultTemplateGroup || template.getTemplateGroup() == null) + { + template.setTemplateGroup(defaultTemplateGroup); + } + + final Template newTemplate = repository.save(template); + return newTemplate.getID(); + } + + @Override + protected String getNameForItem(Template item) + { + return item.getTemplateName(); + } +} diff --git a/src/main/java/de/deadlocker8/budgetmaster/database/importer/TransactionImporter.java b/src/main/java/de/deadlocker8/budgetmaster/database/importer/TransactionImporter.java index 896573e4b..462bb86e7 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/database/importer/TransactionImporter.java +++ b/src/main/java/de/deadlocker8/budgetmaster/database/importer/TransactionImporter.java @@ -29,10 +29,11 @@ public class TransactionImporter extends ItemImporter<Transaction> } LOGGER.debug(MessageFormat.format("Importing transaction with name: {0}, date: {1}", transaction.getName(), transaction.getDate())); + tagImporter.importItems(transaction.getTags()); transaction.setID(null); - final Transaction newTransaction = repository.save(transaction); + final Transaction newTransaction = repository.save(transaction); return newTransaction.getID(); } diff --git a/src/main/java/de/deadlocker8/budgetmaster/services/ImportService.java b/src/main/java/de/deadlocker8/budgetmaster/services/ImportService.java index 190c101f4..eabdb2449 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/services/ImportService.java +++ b/src/main/java/de/deadlocker8/budgetmaster/services/ImportService.java @@ -101,7 +101,8 @@ public class ImportService if(importTemplates) { - importResultItems.add(importTemplates(importTemplateGroups)); + final TemplateGroup defaultTemplateGroup = templateGroupRepository.findFirstByType(TemplateGroupType.DEFAULT); + importResultItems.add(new TemplateImporter(templateRepository, tagImporter, defaultTemplateGroup, !importTemplateGroups).importItems(database.getTemplates())); } else { @@ -228,41 +229,4 @@ public class ImportService return updatedItems; } - - private ImportResultItem importTemplates(Boolean importTemplateGroups) - { - List<Template> templates = database.getTemplates(); - LOGGER.debug(MessageFormat.format("Importing {0} templates...", templates.size())); - - int numberOfImportedTemplates = 0; - - for(int i = 0; i < templates.size(); i++) - { - Template template = templates.get(i); - try - { - LOGGER.debug(MessageFormat.format("Importing template {0}/{1} (templateName: {2})", i + 1, templates.size(), template.getTemplateName())); -// updateTagsForItem(template); - template.setID(null); - - if(!importTemplateGroups || template.getTemplateGroup() == null) - { - template.setTemplateGroup(templateGroupRepository.findFirstByType(TemplateGroupType.DEFAULT)); - } - - templateRepository.save(template); - - numberOfImportedTemplates++; - } - catch(Exception e) - { - final String errorMessage = MessageFormat.format("Error while importing template with name \"{0}\"", template.getTemplateName()); - LOGGER.error(errorMessage, e); - collectedErrorMessages.add(formatErrorMessage(errorMessage, e)); - } - } - - LOGGER.debug(MessageFormat.format("Importing templates DONE ({0}/{1})", numberOfImportedTemplates, templates.size())); - return new ImportResultItem(EntityType.TEMPLATE, numberOfImportedTemplates, templates.size(), collectedErrorMessages); - } } diff --git a/src/test/java/de/deadlocker8/budgetmaster/unit/database/importer/TemplateImporterTest.java b/src/test/java/de/deadlocker8/budgetmaster/unit/database/importer/TemplateImporterTest.java new file mode 100644 index 000000000..f5df78182 --- /dev/null +++ b/src/test/java/de/deadlocker8/budgetmaster/unit/database/importer/TemplateImporterTest.java @@ -0,0 +1,316 @@ +package de.deadlocker8.budgetmaster.unit.database.importer; + +import de.deadlocker8.budgetmaster.accounts.Account; +import de.deadlocker8.budgetmaster.accounts.AccountRepository; +import de.deadlocker8.budgetmaster.accounts.AccountType; +import de.deadlocker8.budgetmaster.categories.Category; +import de.deadlocker8.budgetmaster.categories.CategoryRepository; +import de.deadlocker8.budgetmaster.categories.CategoryType; +import de.deadlocker8.budgetmaster.database.importer.TagImporter; +import de.deadlocker8.budgetmaster.database.importer.TemplateImporter; +import de.deadlocker8.budgetmaster.icon.Icon; +import de.deadlocker8.budgetmaster.icon.IconRepository; +import de.deadlocker8.budgetmaster.services.EntityType; +import de.deadlocker8.budgetmaster.services.ImportResultItem; +import de.deadlocker8.budgetmaster.tags.Tag; +import de.deadlocker8.budgetmaster.tags.TagRepository; +import de.deadlocker8.budgetmaster.templategroup.TemplateGroup; +import de.deadlocker8.budgetmaster.templategroup.TemplateGroupRepository; +import de.deadlocker8.budgetmaster.templategroup.TemplateGroupType; +import de.deadlocker8.budgetmaster.templates.Template; +import de.deadlocker8.budgetmaster.templates.TemplateRepository; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@ExtendWith(SpringExtension.class) +@DataJpaTest +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) +class TemplateImporterTest +{ + @Autowired + private AccountRepository accountRepository; + + @Autowired + private CategoryRepository categoryRepository; + + @Autowired + private TemplateRepository templateRepository; + + @Autowired + private TagRepository tagRepository; + + @Autowired + private IconRepository iconRepository; + + @Autowired + private TemplateGroupRepository templateGroupRepository; + + @Test + void test_importTemplate() + { + Category category = new Category("Awesome Category", "#ff0000", CategoryType.CUSTOM); + category = categoryRepository.save(category); + + Account account = new Account("Awesome Account", AccountType.CUSTOM); + account = accountRepository.save(account); + + Account transferAccount = new Account("Transfer Account", AccountType.CUSTOM); + transferAccount = accountRepository.save(transferAccount); + + Icon icon = new Icon("fas fa-icons"); + icon = iconRepository.save(icon); + + final Template template = new Template(); + template.setID(15); + template.setTemplateName("My awesome template"); + template.setName("My transaction"); + template.setAmount(-100); + template.setIsExpenditure(true); + template.setCategory(category); + template.setAccount(account); + template.setTags(List.of()); + template.setDescription("Lorem Ipsum"); + template.setIconReference(icon); + template.setTransferAccount(transferAccount); + + TemplateGroup defaultTemplateGroup = new TemplateGroup("Default group", TemplateGroupType.DEFAULT); + defaultTemplateGroup = templateGroupRepository.save(defaultTemplateGroup); + + final TagImporter tagImporter = new TagImporter(tagRepository); + final TemplateImporter importer = new TemplateImporter(templateRepository, tagImporter, defaultTemplateGroup, false); + final ImportResultItem resultItem = importer.importItems(List.of(template)); + + final ImportResultItem expected = new ImportResultItem(EntityType.TEMPLATE, 1, 1, List.of()); + assertThat(resultItem).isEqualTo(expected); + + final List<Template> templates = templateRepository.findAll(); + assertThat(templates).hasSize(1); + final Template actualTemplate = templates.get(0); + assertThat(actualTemplate) + .hasFieldOrPropertyWithValue("ID", 1) + .hasFieldOrPropertyWithValue("templateName", "My awesome template") + .hasFieldOrPropertyWithValue("name", "My transaction") + .hasFieldOrPropertyWithValue("amount", -100) + .hasFieldOrPropertyWithValue("isExpenditure", true) + .hasFieldOrPropertyWithValue("category", category) + .hasFieldOrPropertyWithValue("account", account) + .hasFieldOrPropertyWithValue("description", "Lorem Ipsum") + .hasFieldOrPropertyWithValue("transferAccount", transferAccount) + .hasFieldOrPropertyWithValue("templateGroup", defaultTemplateGroup) + .hasFieldOrPropertyWithValue("iconReference", icon); + assertThat(actualTemplate.getTags()).isEmpty(); + } + + @Test + void test_importTemplateWithTags() + { + Category category = new Category("Awesome Category", "#ff0000", CategoryType.CUSTOM); + category = categoryRepository.save(category); + + Account account = new Account("Awesome Account", AccountType.CUSTOM); + account = accountRepository.save(account); + + Icon icon = new Icon("fas fa-icons"); + icon = iconRepository.save(icon); + + final Template template = new Template(); + template.setID(15); + template.setTemplateName("My awesome template"); + template.setName("My transaction"); + template.setAmount(-100); + template.setIsExpenditure(true); + template.setCategory(category); + template.setAccount(account); + template.setTags(List.of()); + template.setDescription("Lorem Ipsum"); + template.setIconReference(icon); + + final Tag tag1 = new Tag("0815"); + tag1.setID(1); + final Tag tag2 = new Tag("Apple Pie"); + tag2.setID(2); + template.setTags(List.of(tag1, tag2)); + + TemplateGroup defaultTemplateGroup = new TemplateGroup("Default group", TemplateGroupType.DEFAULT); + defaultTemplateGroup = templateGroupRepository.save(defaultTemplateGroup); + + final TagImporter tagImporter = new TagImporter(tagRepository); + final TemplateImporter importer = new TemplateImporter(templateRepository, tagImporter, defaultTemplateGroup, false); + final ImportResultItem resultItem = importer.importItems(List.of(template)); + + final ImportResultItem expected = new ImportResultItem(EntityType.TEMPLATE, 1, 1, List.of()); + assertThat(resultItem).isEqualTo(expected); + + final List<Template> templates = templateRepository.findAll(); + assertThat(templates).hasSize(1); + final Template actualTemplate = templates.get(0); + assertThat(actualTemplate) + .hasFieldOrPropertyWithValue("ID", 1) + .hasFieldOrPropertyWithValue("templateName", "My awesome template") + .hasFieldOrPropertyWithValue("name", "My transaction") + .hasFieldOrPropertyWithValue("amount", -100) + .hasFieldOrPropertyWithValue("isExpenditure", true) + .hasFieldOrPropertyWithValue("category", category) + .hasFieldOrPropertyWithValue("account", account) + .hasFieldOrPropertyWithValue("description", "Lorem Ipsum") + .hasFieldOrPropertyWithValue("transferAccount", null) + .hasFieldOrPropertyWithValue("templateGroup", defaultTemplateGroup) + .hasFieldOrPropertyWithValue("iconReference", icon); + + final Tag expectedTag1 = new Tag("0815"); + expectedTag1.setID(1); + final Tag expectedTag2 = new Tag("Apple Pie"); + expectedTag2.setID(2); + assertThat(actualTemplate.getTags()) + .containsExactly(expectedTag1, expectedTag2); + } + + @Test + void test_test_importMultipleTemplatesWithSomeSimilarTags() + { + Category category = new Category("Awesome Category", "#ff0000", CategoryType.CUSTOM); + category = categoryRepository.save(category); + + Account account = new Account("Awesome Account", AccountType.CUSTOM); + account = accountRepository.save(account); + + Icon icon = new Icon("fas fa-icons"); + icon = iconRepository.save(icon); + + final Tag tag1 = new Tag("0815"); + tag1.setID(1); + final Tag tag2 = new Tag("Apple Pie"); + tag2.setID(2); + + final Template template = new Template(); + template.setID(15); + template.setTemplateName("My awesome template"); + template.setName("My transaction"); + template.setAmount(-100); + template.setIsExpenditure(true); + template.setCategory(category); + template.setAccount(account); + template.setTags(List.of()); + template.setDescription("Lorem Ipsum"); + template.setIconReference(icon); + template.setTags(List.of(tag1, tag2)); + + final Template template2 = new Template(); + template2.setID(16); + template2.setTemplateName("My awesome template 2"); + template2.setIsExpenditure(true); + template2.setTags(List.of()); + template2.setDescription("Lorem Ipsum"); + template2.setIconReference(icon); + template2.setTags(List.of(tag1)); + + TemplateGroup defaultTemplateGroup = new TemplateGroup("Default group", TemplateGroupType.DEFAULT); + defaultTemplateGroup = templateGroupRepository.save(defaultTemplateGroup); + + final TagImporter tagImporter = new TagImporter(tagRepository); + final TemplateImporter importer = new TemplateImporter(templateRepository, tagImporter, defaultTemplateGroup, false); + final ImportResultItem resultItem = importer.importItems(List.of(template, template2)); + + final ImportResultItem expected = new ImportResultItem(EntityType.TEMPLATE, 2, 2, List.of()); + assertThat(resultItem).isEqualTo(expected); + + final List<Template> templates = templateRepository.findAll(); + assertThat(templates).hasSize(2); + final Template actualTemplate = templates.get(0); + assertThat(actualTemplate) + .hasFieldOrPropertyWithValue("ID", 1) + .hasFieldOrPropertyWithValue("templateName", "My awesome template"); + + final Tag expectedTag1 = new Tag("0815"); + expectedTag1.setID(1); + final Tag expectedTag2 = new Tag("Apple Pie"); + expectedTag2.setID(2); + assertThat(actualTemplate.getTags()) + .containsExactly(expectedTag1, expectedTag2); + + final Template actualTemplate2 = templates.get(1); + assertThat(actualTemplate2) + .hasFieldOrPropertyWithValue("ID", 2) + .hasFieldOrPropertyWithValue("templateName", "My awesome template 2"); + + assertThat(actualTemplate2.getTags()) + .containsExactly(expectedTag1); + + + assertThat(tagRepository.findAll()).hasSize(2); + } + + @Test + void test_importTemplateWithTemplateGroup() + { + final Template template = new Template(); + template.setID(15); + template.setTemplateName("My awesome template"); + template.setName("My transaction"); + template.setIsExpenditure(true); + template.setTags(List.of()); + + TemplateGroup templateGroup = new TemplateGroup("My group", TemplateGroupType.CUSTOM); + templateGroup = templateGroupRepository.save(templateGroup); + template.setTemplateGroup(templateGroup); + + TemplateGroup defaultTemplateGroup = new TemplateGroup("Default group", TemplateGroupType.DEFAULT); + defaultTemplateGroup = templateGroupRepository.save(defaultTemplateGroup); + + final TagImporter tagImporter = new TagImporter(tagRepository); + final TemplateImporter importer = new TemplateImporter(templateRepository, tagImporter, defaultTemplateGroup, false); + final ImportResultItem resultItem = importer.importItems(List.of(template)); + + final ImportResultItem expected = new ImportResultItem(EntityType.TEMPLATE, 1, 1, List.of()); + assertThat(resultItem).isEqualTo(expected); + + final List<Template> templates = templateRepository.findAll(); + assertThat(templates).hasSize(1); + final Template actualTemplate = templates.get(0); + assertThat(actualTemplate) + .hasFieldOrPropertyWithValue("ID", 1) + .hasFieldOrPropertyWithValue("templateGroup", templateGroup); + assertThat(actualTemplate.getTags()).isEmpty(); + } + + @Test + void test_importTemplateAlwaysAssignDefaultTemplateGroup() + { + final Template template = new Template(); + template.setID(15); + template.setTemplateName("My awesome template"); + template.setName("My transaction"); + template.setIsExpenditure(true); + template.setTags(List.of()); + + TemplateGroup templateGroup = new TemplateGroup("My group", TemplateGroupType.CUSTOM); + templateGroup = templateGroupRepository.save(templateGroup); + template.setTemplateGroup(templateGroup); + + TemplateGroup defaultTemplateGroup = new TemplateGroup("Default group", TemplateGroupType.DEFAULT); + defaultTemplateGroup = templateGroupRepository.save(defaultTemplateGroup); + + final TagImporter tagImporter = new TagImporter(tagRepository); + final TemplateImporter importer = new TemplateImporter(templateRepository, tagImporter, defaultTemplateGroup, true); + final ImportResultItem resultItem = importer.importItems(List.of(template)); + + final ImportResultItem expected = new ImportResultItem(EntityType.TEMPLATE, 1, 1, List.of()); + assertThat(resultItem).isEqualTo(expected); + + final List<Template> templates = templateRepository.findAll(); + assertThat(templates).hasSize(1); + final Template actualTemplate = templates.get(0); + assertThat(actualTemplate) + .hasFieldOrPropertyWithValue("ID", 1) + .hasFieldOrPropertyWithValue("templateGroup", defaultTemplateGroup); + assertThat(actualTemplate.getTags()).isEmpty(); + } +} \ No newline at end of file -- GitLab