From 40f7db9dc7ad2d5fc77d122a2b678da12849fa58 Mon Sep 17 00:00:00 2001 From: Dmitrii Cravcenco Date: Wed, 6 Dec 2023 16:54:05 +0200 Subject: [PATCH 1/5] Add file for tesing income service --- .../service/IncomeServiceTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/test/java/com/faf223/expensetrackerfaf/service/IncomeServiceTest.java diff --git a/src/test/java/com/faf223/expensetrackerfaf/service/IncomeServiceTest.java b/src/test/java/com/faf223/expensetrackerfaf/service/IncomeServiceTest.java new file mode 100644 index 0000000..57a015b --- /dev/null +++ b/src/test/java/com/faf223/expensetrackerfaf/service/IncomeServiceTest.java @@ -0,0 +1,26 @@ +package com.faf223.expensetrackerfaf.service; + +import com.faf223.expensetrackerfaf.repository.IncomeRepository; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class IncomeServiceTest { + + @Mock + private IncomeRepository incomeRepository; + + @InjectMocks + private IncomeService incomeService; + + @Test + public void IncomeService_CreateIncome_ReturnsIncome() { + + + + } + +} -- 2.49.1 From 2a83718dd6b01a04e6d5d861e583700bb4622ca3 Mon Sep 17 00:00:00 2001 From: Dmitrii Cravcenco Date: Wed, 6 Dec 2023 17:23:05 +0200 Subject: [PATCH 2/5] Lombok optimization --- .../dto/mappers/ExpenseMapper.java | 10 ++----- .../dto/mappers/IncomeMapper.java | 10 ++----- .../service/IncomeServiceTest.java | 27 ++++++++++++++++++- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/faf223/expensetrackerfaf/dto/mappers/ExpenseMapper.java b/src/main/java/com/faf223/expensetrackerfaf/dto/mappers/ExpenseMapper.java index 9bc257f..654dbee 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/dto/mappers/ExpenseMapper.java +++ b/src/main/java/com/faf223/expensetrackerfaf/dto/mappers/ExpenseMapper.java @@ -5,25 +5,19 @@ import com.faf223.expensetrackerfaf.dto.ExpenseDTO; import com.faf223.expensetrackerfaf.model.Expense; import com.faf223.expensetrackerfaf.service.ExpenseCategoryService; import com.faf223.expensetrackerfaf.service.ExpenseService; +import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.time.LocalDate; @Component +@RequiredArgsConstructor public class ExpenseMapper { - private final ExpenseService expenseService; private final ExpenseCategoryService expenseCategoryService; private final UserMapper userMapper; - @Autowired - public ExpenseMapper(ExpenseService expenseService, ExpenseCategoryService expenseCategoryService, UserMapper userMapper) { - this.expenseService = expenseService; - this.expenseCategoryService = expenseCategoryService; - this.userMapper = userMapper; - } - public ExpenseDTO toDto(Expense expense) { return new ExpenseDTO(expense.getId(), userMapper.toDto(expense.getUser()), expense.getCategory(), expense.getDate(), expense.getAmount()); diff --git a/src/main/java/com/faf223/expensetrackerfaf/dto/mappers/IncomeMapper.java b/src/main/java/com/faf223/expensetrackerfaf/dto/mappers/IncomeMapper.java index a59a2dd..b3059ce 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/dto/mappers/IncomeMapper.java +++ b/src/main/java/com/faf223/expensetrackerfaf/dto/mappers/IncomeMapper.java @@ -6,25 +6,19 @@ import com.faf223.expensetrackerfaf.model.Expense; import com.faf223.expensetrackerfaf.model.Income; import com.faf223.expensetrackerfaf.service.IncomeCategoryService; import com.faf223.expensetrackerfaf.service.IncomeService; +import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.time.LocalDate; @Component +@RequiredArgsConstructor public class IncomeMapper { - private final IncomeService incomeService; private final IncomeCategoryService incomeCategoryService; private final UserMapper userMapper; - @Autowired - public IncomeMapper(IncomeService incomeService, IncomeCategoryService incomeCategoryService, UserMapper userMapper) { - this.incomeService = incomeService; - this.incomeCategoryService = incomeCategoryService; - this.userMapper = userMapper; - } - public IncomeDTO toDto(Income income) { return new IncomeDTO(income.getId(), userMapper.toDto(income.getUser()), income.getCategory(), income.getDate(), income.getAmount()); diff --git a/src/test/java/com/faf223/expensetrackerfaf/service/IncomeServiceTest.java b/src/test/java/com/faf223/expensetrackerfaf/service/IncomeServiceTest.java index 57a015b..bcb74ca 100644 --- a/src/test/java/com/faf223/expensetrackerfaf/service/IncomeServiceTest.java +++ b/src/test/java/com/faf223/expensetrackerfaf/service/IncomeServiceTest.java @@ -1,24 +1,49 @@ package com.faf223.expensetrackerfaf.service; +import com.faf223.expensetrackerfaf.model.Income; +import com.faf223.expensetrackerfaf.model.IncomeCategory; +import com.faf223.expensetrackerfaf.model.User; +import com.faf223.expensetrackerfaf.repository.IncomeCategoryRepository; import com.faf223.expensetrackerfaf.repository.IncomeRepository; +import com.faf223.expensetrackerfaf.repository.UserRepository; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.Optional; + @ExtendWith(MockitoExtension.class) public class IncomeServiceTest { @Mock private IncomeRepository incomeRepository; - + @Mock + private IncomeCategoryRepository incomeCategoryRepository; + @Mock + private UserRepository userRepository; @InjectMocks private IncomeService incomeService; @Test public void IncomeService_CreateIncome_ReturnsIncome() { + // TODO: move income creation to service or move this test to controller tests + Optional user = userRepository.findByUsername("Deep Deep"); + Assertions.assertThat(user.isPresent()).isTrue(); + IncomeCategory incomeCategory = incomeCategoryRepository.getReferenceById(4L); + + Income income = Income.builder() + .user(user.get()) + .amount(BigDecimal.valueOf(700)) + .category(incomeCategory) + .date(LocalDate.of(2023,10,5)) + .build(); + } -- 2.49.1 From cf9a18cd336679d441530490351007e0e177ab19 Mon Sep 17 00:00:00 2001 From: Dmitrii Cravcenco Date: Fri, 8 Dec 2023 17:45:43 +0200 Subject: [PATCH 3/5] Add income service test function --- .../model/IncomeCategory.java | 6 ++++ .../service/IncomeServiceTest.java | 34 +++++++++++++++---- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/faf223/expensetrackerfaf/model/IncomeCategory.java b/src/main/java/com/faf223/expensetrackerfaf/model/IncomeCategory.java index 6fd4f99..ac6f393 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/model/IncomeCategory.java +++ b/src/main/java/com/faf223/expensetrackerfaf/model/IncomeCategory.java @@ -3,10 +3,16 @@ package com.faf223.expensetrackerfaf.model; import jakarta.persistence.*; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; @Data @Entity(name = "income_categories") +@Builder +@NoArgsConstructor +@AllArgsConstructor public class IncomeCategory implements IMoneyTransactionCategory { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/test/java/com/faf223/expensetrackerfaf/service/IncomeServiceTest.java b/src/test/java/com/faf223/expensetrackerfaf/service/IncomeServiceTest.java index bcb74ca..8b0e8c3 100644 --- a/src/test/java/com/faf223/expensetrackerfaf/service/IncomeServiceTest.java +++ b/src/test/java/com/faf223/expensetrackerfaf/service/IncomeServiceTest.java @@ -1,5 +1,6 @@ package com.faf223.expensetrackerfaf.service; +import com.faf223.expensetrackerfaf.model.IMoneyTransaction; import com.faf223.expensetrackerfaf.model.Income; import com.faf223.expensetrackerfaf.model.IncomeCategory; import com.faf223.expensetrackerfaf.model.User; @@ -11,12 +12,17 @@ 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.mockito.junit.jupiter.MockitoExtension; import java.math.BigDecimal; import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; +import static org.mockito.Mockito.when; + @ExtendWith(MockitoExtension.class) public class IncomeServiceTest { @@ -29,22 +35,38 @@ public class IncomeServiceTest { @InjectMocks private IncomeService incomeService; +// public void createOrUpdate(IMoneyTransaction income) { +// incomeRepository.save((Income) income); +// } + @Test public void IncomeService_CreateIncome_ReturnsIncome() { - // TODO: move income creation to service or move this test to controller tests - Optional user = userRepository.findByUsername("Deep Deep"); - Assertions.assertThat(user.isPresent()).isTrue(); - IncomeCategory incomeCategory = incomeCategoryRepository.getReferenceById(4L); + User user = User.builder().build(); + when(userRepository.findByUsername("Deep Deep")).thenReturn(Optional.of(user)); + user = userRepository.findByUsername("Deep Deep").get(); + + IncomeCategory incomeCategory = IncomeCategory.builder().build(); + when(incomeCategoryRepository.findById(1L)).thenReturn(Optional.of(incomeCategory)); + incomeCategory = incomeCategoryRepository.findById(1L).get(); Income income = Income.builder() - .user(user.get()) - .amount(BigDecimal.valueOf(700)) + .user(user) + .amount(BigDecimal.valueOf(111)) .category(incomeCategory) .date(LocalDate.of(2023,10,5)) .build(); + when(incomeRepository.save(Mockito.any(Income.class))).thenReturn(income); + incomeService.createOrUpdate(income); + Assertions.assertThat(income.getId()).isGreaterThan(0); + + List incomes = new ArrayList<>(); + when(incomeRepository.findByUser(user)).thenReturn(List.of(income)); + incomes = incomeRepository.findByUser(user); + + // TODO: finish service test } -- 2.49.1 From a373daa58c619b347ffdef26cee232e823be665e Mon Sep 17 00:00:00 2001 From: Dmitrii Cravcenco Date: Sun, 10 Dec 2023 12:59:26 +0200 Subject: [PATCH 4/5] Make income/expense return created instance's id --- .../controller/ExpenseController.java | 10 +++++----- .../controller/IncomeController.java | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java b/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java index 4e092d0..18432c9 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java @@ -28,9 +28,7 @@ import org.springframework.web.bind.annotation.*; import java.time.LocalDate; import java.time.Month; -import java.util.Collections; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; @RestController @@ -52,7 +50,7 @@ public class ExpenseController { } @PostMapping() - public ResponseEntity createNewExpense(@RequestBody @Valid ExpenseCreationDTO expenseDTO, + public ResponseEntity> createNewExpense(@RequestBody @Valid ExpenseCreationDTO expenseDTO, BindingResult bindingResult) { if(bindingResult.hasErrors()) throw new TransactionNotCreatedException("Could not create new expense"); @@ -68,7 +66,9 @@ public class ExpenseController { expense.setUser(user); expenseService.createOrUpdate(expense); - return ResponseEntity.status(HttpStatus.CREATED).build(); + Map response = new HashMap<>(); + response.put("expenseId", expense.getId()); + return ResponseEntity.status(HttpStatus.CREATED).body(response); } throw new TransactionNotCreatedException("Could not create new expense"); diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java b/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java index 1a9f179..d73d0fb 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java @@ -28,9 +28,7 @@ import org.springframework.web.bind.annotation.*; import java.time.LocalDate; import java.time.Month; -import java.util.Collections; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; @RestController @@ -52,7 +50,7 @@ public class IncomeController { } @PostMapping() - public ResponseEntity createNewIncome(@RequestBody @Valid IncomeCreationDTO incomeDTO, + public ResponseEntity> createNewIncome(@RequestBody @Valid IncomeCreationDTO incomeDTO, BindingResult bindingResult) { if(bindingResult.hasErrors()) throw new TransactionNotCreatedException(ErrorResponse.from(bindingResult).getMessage()); @@ -68,10 +66,12 @@ public class IncomeController { income.setUser(user); incomeService.createOrUpdate(income); - return ResponseEntity.status(HttpStatus.CREATED).build(); + Map response = new HashMap<>(); + response.put("incomeId", income.getId()); + return ResponseEntity.status(HttpStatus.CREATED).body(response); } - throw new TransactionNotCreatedException("Could not create new expense"); + throw new TransactionNotCreatedException("Could not create new income"); } @PatchMapping("/update/{id}") -- 2.49.1 From ee4c885ae6accb295e34e0402479f134d7a0a7f5 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 10 Dec 2023 13:57:07 +0200 Subject: [PATCH 5/5] Front upd --- .../web/src/routes/dashboard/+page.svelte | 32 +- .../routes/dashboard/board/Dashboard.svelte | 9 +- .../dashboard/board/ExpenseDashboard.svelte | 35 +- .../expenses/infolists/ContentExpense.svelte | 22 +- .../board/expenses/infolists/Expenses.svelte | 353 +++++++++++++- .../board/expenses/infolists/Modal.svelte | 57 --- .../board/expenses/other/DataMenu.svelte | 437 ------------------ .../board/expenses/other/QuickInfobar.svelte | 9 +- .../src/routes/dashboard/menu/SideMenu.svelte | 7 + .../routes/dashboard/menu/StickyMenu.svelte | 171 +++++++ 10 files changed, 612 insertions(+), 520 deletions(-) delete mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/Modal.svelte delete mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/DataMenu.svelte create mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/menu/StickyMenu.svelte diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/+page.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/+page.svelte index 42adfe0..01f3657 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/+page.svelte +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/+page.svelte @@ -3,15 +3,37 @@ import SideMenu from './menu/SideMenu.svelte'; import {selectedTab} from "./stores.js"; import {globalStyles} from "./styles.js"; + import StickyMenu from "./menu/StickyMenu.svelte"; + import {onMount} from "svelte"; function handleTabClick(tab) { selectedTab.set(tab); } + let screenWidth; + + onMount(() => { + screenWidth = window.innerWidth; + const handleResize = () => { + console.log(screenWidth); + screenWidth = window.innerWidth; + }; + + window.addEventListener('resize', handleResize); + + return () => { + window.removeEventListener('resize', handleResize); + }; + }); +
- + {#if screenWidth < 900} + + {:else} + + {/if}
@@ -19,10 +41,18 @@ @import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400'); #wrapper { + padding: 0; + margin: 0; display: flex; align-items: stretch; min-height: 100vh; max-height: 100%; transition: all 0.3s cubic-bezier(.25,.8,.25,1); } + + @media only screen and (max-width: 900px) { + #wrapper { + flex-direction: column; + } + } \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/Dashboard.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/Dashboard.svelte index a956f8a..33bb66a 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/Dashboard.svelte +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/Dashboard.svelte @@ -76,7 +76,6 @@ font-family: 'Source Sans Pro', sans-serif; border-radius: 20px; margin: 20px; - padding: 20px 20px 0; min-width: 100px; display: flex; flex: 1 1 auto; @@ -85,4 +84,12 @@ justify-content: stretch; transition: all 0.3s cubic-bezier(.25,.8,.25,1); } + + @media only screen and (max-width: 900px) { + #dashboard { + margin: 0; + flex-wrap: wrap; + width: 100%; + } + } diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/ExpenseDashboard.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/ExpenseDashboard.svelte index 63c3b79..a7ca6a3 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/ExpenseDashboard.svelte +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/ExpenseDashboard.svelte @@ -1,9 +1,36 @@ - - - +
+
+ + +
+ +
+ + + diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/ContentExpense.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/ContentExpense.svelte index b65dbbd..29dfc17 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/ContentExpense.svelte +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/ContentExpense.svelte @@ -1,12 +1,11 @@
-

Expenses

-
(showModal = true)} on:keydown={() => console.log("keydown")}> +

Expenses: {$dateText}

+
console.log("keydown")}> +
- -
+ {#if showModal} +

Expense Details

@@ -96,7 +99,7 @@
- + {/if}
@@ -134,6 +137,7 @@ padding: 20px; max-width: 400px; margin: 0 auto; + color: black; } h3 { diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/Expenses.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/Expenses.svelte index 0f28cb4..de0ddc8 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/Expenses.svelte +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/Expenses.svelte @@ -1,7 +1,11 @@
+
+ + + +
    - {#each $expenseData.reverse() as item} -
  • + {#each $expenseData.toReversed() as item (item.expenseId)} +
  • {#if textToIcon[item.expenseCategory.name]} {@html textToIcon[item.expenseCategory.name]} @@ -32,8 +246,24 @@ {item.incomeCategory ? `${item.incomeCategory.name}: ` : `${item.expenseCategory.name}: `} {item.incomeCategory ? `+${item.amount}$` : `-${item.amount}$`} - {`${item.date}`} + {`${item.date}`} + + + +
  • + {#if dropdownStates[item.expenseId]} +
    + + + +
    + + +
    + +
    + {/if} {/each}
@@ -41,13 +271,51 @@ diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/Modal.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/Modal.svelte deleted file mode 100644 index fca4643..0000000 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/Modal.svelte +++ /dev/null @@ -1,57 +0,0 @@ - - - - (showModal = false)} - on:click|self={() => dialog.close()} -> - -
- - -
-
- - diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/DataMenu.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/DataMenu.svelte deleted file mode 100644 index c03fb20..0000000 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/DataMenu.svelte +++ /dev/null @@ -1,437 +0,0 @@ - - -
-
- - - - - -
-
-
- -
-
- -
- -
- -
- - \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/QuickInfobar.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/QuickInfobar.svelte index e150a09..9c64799 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/QuickInfobar.svelte +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/QuickInfobar.svelte @@ -49,14 +49,17 @@ #quickInfobar { display: flex; justify-content: space-between; + flex-wrap: wrap; + min-height: 0; + flex: 1 1 auto; margin: 20px; } .infobarElement { margin: 10px; - width: 200px; - min-width: 100px; - height: 100px; + min-width: 0px; + min-height: 0px; + flex: 1 1 auto; color: white; padding: 10px; border-radius: 10px; diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/menu/SideMenu.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/menu/SideMenu.svelte index 69286ab..8094d22 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/menu/SideMenu.svelte +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/menu/SideMenu.svelte @@ -91,6 +91,7 @@
\ No newline at end of file -- 2.49.1