Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,5 @@ To run all back-end unit and integration tests (full code coverage):
```
2. Run the tests:
```bash

mvn test
```
16 changes: 16 additions & 0 deletions backend/src/main/java/com/inventory/backend/config/WebConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.inventory.backend.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

@Configuration
public class WebConfig implements WebMvcConfigurer{
@Override
public void addCorsMappings(CorsRegistry registry){
registry.addMapping("/**")
.allowedOrigins("http://localhost:8080")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public ProductController(ProductService service) {
@GetMapping
public ProductPage getProducts(
@RequestParam Optional<String> name,
@RequestParam Optional<List<String>> category,
@RequestParam Optional<String> category,
@RequestParam Optional<Boolean> availability,
@RequestParam Optional<String> sortBy,
@RequestParam Optional<String> sortBy2,
Expand All @@ -33,10 +33,10 @@ public ProductPage getProducts(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size
){
Set<String> categorySet = category.map(HashSet::new).orElse(null);
//Set<String> categorySet = category.map(HashSet::new).orElse(null);
return service.getFilteredProductsPage(
name,
Optional.ofNullable(categorySet),
category,
availability,
sortBy,
sortBy2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ public void clear() {

public List<Product> findByNameOrCategoryOrAvailability(
Optional<String> nameFilter,
Optional<Set<String>> categoryFilter,
Optional<String> categoryFilter,
Optional<Boolean> availability
) {
return products.values().stream()
.filter(p -> nameFilter.map(name -> p.getName().toLowerCase().contains(name.toLowerCase())).orElse(true))
.filter(p -> categoryFilter.map(categories -> categories.contains(p.getCategory())).orElse(true))
.filter(p -> categoryFilter.filter(cat -> !cat.isBlank()).map(cat -> cat.equalsIgnoreCase(p.getCategory())).orElse(true))
.filter(p -> availability.map(avail -> avail == p.isInStock()).orElse(true))
.collect(Collectors.toList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public ProductService(ProductRepository repository) {

public List<Product> getFilteredAndSortedProducts(
Optional<String> nameFilter,
Optional<Set<String>> categoryFilter,
Optional<String> categoryFilter,
Optional<Boolean> availability,
Optional<String> sortBy,
Optional<String> sortBy2,
Expand All @@ -45,7 +45,7 @@ public List<Product> getFilteredAndSortedProducts(
}
public ProductPage getFilteredProductsPage(
Optional<String> nameFilter,
Optional<Set<String>> categoryFilter,
Optional<String> categoryFilter,
Optional<Boolean> availability,
Optional<String> sortBy,
Optional<String> sortBy2,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.inventory.backend.model;

public class InventoryMetricsTest {
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

import com.inventory.backend.dto.ProductDTO;
import com.inventory.backend.model.Product;
import com.inventory.backend.model.InventoryMetrics;
import com.inventory.backend.repository.ProductRepository;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.Optional;
import java.util.Set;
import java.util.UUID;

import static org.junit.jupiter.api.Assertions.*;
Expand Down Expand Up @@ -52,4 +57,74 @@ void markOutOfStock_shouldSetQuantityToZero() {
Product updated = repository.findById(id).orElseThrow();
assertEquals(0, updated.getQuantityInStock());
}

@Test
void shouldCalculateMetricsByCategory() {
ProductDTO dto = new ProductDTO();
dto.setName("Mouse");
dto.setCategory("Electronics");
dto.setUnitPrice(10.0);
dto.setQuantityInStock(5);
service.createProduct(dto);

ProductDTO dto2 = new ProductDTO();
dto2.setName("book");
dto2.setCategory("Books");
dto2.setUnitPrice(20.0);
dto2.setQuantityInStock(10);
service.createProduct(dto2);

InventoryMetrics metrics = service.getMetrics();
assertEquals(15, metrics.getTotalInStock());
assertTrue(metrics.getByCategory().containsKey("Books"));
assertTrue(metrics.getByCategory().containsKey("Electronics"));
}

@Test
void shouldFailValidationOnInvalidDTO() {
ProductDTO dto = new ProductDTO();
dto.setName("");
dto.setCategory("");
dto.setUnitPrice(-10.0);
dto.setQuantityInStock(-2);

Set<ConstraintViolation<ProductDTO>> violations = Validation.buildDefaultValidatorFactory()
.getValidator()
.validate(dto);

assertEquals(4, violations.size());
}

@Test
void shouldSortByNameAndStock() {
ProductDTO dto1 = new ProductDTO();
dto1.setName("AAA");
dto1.setCategory("Cat1");
dto1.setUnitPrice(10.0);
dto1.setQuantityInStock(5);

ProductDTO dto2 = new ProductDTO();
dto2.setName("AAA");
dto2.setCategory("Cat2");
dto2.setUnitPrice(20.0);
dto2.setQuantityInStock(2);

service.createProduct(dto1);
service.createProduct(dto2);

var result = service.getFilteredAndSortedProducts(
Optional.empty(),
Optional.empty(),
Optional.empty(),
Optional.of("name"),
Optional.of("quantityInStock"),
true,
false,
0,
10
);

assertEquals(5, result.get(0).getQuantityInStock());
assertEquals(2, result.get(1).getQuantityInStock());
}
}
15 changes: 15 additions & 0 deletions frontend/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: "ts-jest",
testEnvironment: "jsdom",
transform: {
"^.+\\.(ts|tsx)$": "ts-jest"
},
transformIgnorePatterns: [
"/node_modules/(?!(axios|react-icons)/)"
],
moduleNameMapper: {
"\\.(css|less|scss|sass)$": "identity-obj-proxy"
},
setupFilesAfterEnv: ["<rootDir>/src/setupTests.ts"]
};
146 changes: 63 additions & 83 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading