diff --git a/ThunderClient/EndpointTests.json b/ThunderClient/EndpointTests.json index 370824e..f411345 100644 --- a/ThunderClient/EndpointTests.json +++ b/ThunderClient/EndpointTests.json @@ -1,7 +1,7 @@ { "client": "Thunder Client", "collectionName": "SmartInventory", - "dateExported": "2024-03-29T06:44:41.033Z", + "dateExported": "2024-03-29T15:11:15.315Z", "version": "1.1", "folders": [ { @@ -17,6 +17,13 @@ "containerId": "", "created": "2024-03-29T06:21:13.542Z", "sortNum": 20000 + }, + { + "_id": "0db7fba9-c06d-462f-a621-ce608d52ea78", + "name": "Review", + "containerId": "", + "created": "2024-03-29T12:28:07.289Z", + "sortNum": 30000 } ], "requests": [ @@ -143,22 +150,27 @@ "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", "containerId": "605122de-fb92-469e-ae99-ed47c68b3d96", "name": "Add Review to Customer", - "url": "http://localhost:9090/customers/{id}/reviews", + "url": "http://localhost:9090/customers/{id}/products/{productId}/reviews", "method": "POST", "sortNum": 80000, "created": "2024-03-29T06:19:27.794Z", - "modified": "2024-03-29T06:19:27.794Z", + "modified": "2024-03-29T15:08:54.672Z", "headers": [], "params": [ { "name": "id", "value": "1", "isPath": true + }, + { + "name": "productId", + "value": "5", + "isPath": true } ], "body": { "type": "json", - "raw": "{\n \"category\": \"Books\",\n \"reviewContent\": \"Expected more from the ending, felt rushed.\",\n \"rating\": 3 ,\n \"productId\": 1 \n}", + "raw": "{\n \"category\": \"Books\",\n \"reviewContent\": \"Expected more from the ending, felt rushed.\",\n \"rating\": 4\n}", "form": [] }, "tests": [] @@ -196,6 +208,20 @@ "params": [], "tests": [] }, + { + "_id": "2540b4c8-bce7-44d1-8a4e-b020e48cf099", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "0db7fba9-c06d-462f-a621-ce608d52ea78", + "name": "Get All Reviews", + "url": "http://localhost:9090/reviews", + "method": "GET", + "sortNum": 100000, + "created": "2024-03-29T12:28:07.290Z", + "modified": "2024-03-29T12:31:37.627Z", + "headers": [], + "params": [], + "tests": [] + }, { "_id": "55a70043-6bf7-451d-b62b-8ac0a1b825f6", "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", @@ -205,12 +231,32 @@ "method": "GET", "sortNum": 110000, "created": "2024-03-29T06:27:57.526Z", - "modified": "2024-03-29T06:32:00.602Z", + "modified": "2024-03-29T09:29:04.154Z", "headers": [], "params": [ { "name": "id", - "value": "7", + "value": "6", + "isPath": true + } + ], + "tests": [] + }, + { + "_id": "20641995-f278-4f9a-9617-e551ed4b932d", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "0db7fba9-c06d-462f-a621-ce608d52ea78", + "name": "Get 1 Review", + "url": "http://localhost:9090/reviews/{id}", + "method": "GET", + "sortNum": 110000, + "created": "2024-03-29T12:28:07.291Z", + "modified": "2024-03-29T14:09:12.966Z", + "headers": [], + "params": [ + { + "name": "id", + "value": "2", "isPath": true } ], @@ -265,12 +311,12 @@ "method": "PUT", "sortNum": 130000, "created": "2024-03-29T06:28:09.610Z", - "modified": "2024-03-29T06:38:03.934Z", + "modified": "2024-03-29T09:29:21.073Z", "headers": [], "params": [ { "name": "id", - "value": "7", + "value": "6", "isPath": true } ], @@ -300,6 +346,26 @@ } ], "tests": [] + }, + { + "_id": "fb7039d9-56e5-4883-995c-d06a7eea82b0", + "colId": "e34b9201-d6f7-4614-a21c-21c245c1032e", + "containerId": "0db7fba9-c06d-462f-a621-ce608d52ea78", + "name": "Delete Product", + "url": "http://localhost:9090/reviews/{id}", + "method": "DELETE", + "sortNum": 140000, + "created": "2024-03-29T12:28:07.295Z", + "modified": "2024-03-29T12:38:39.979Z", + "headers": [], + "params": [ + { + "name": "id", + "value": "9", + "isPath": true + } + ], + "tests": [] } ] } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/controllers/CustomerController.java b/src/main/java/sg/com/smartinventory/controllers/CustomerController.java index 3c0735c..5b953bf 100644 --- a/src/main/java/sg/com/smartinventory/controllers/CustomerController.java +++ b/src/main/java/sg/com/smartinventory/controllers/CustomerController.java @@ -28,71 +28,72 @@ @RestController @RequestMapping("/customers") public class CustomerController { - private CustomerService customerService; - - // @Autowired - public CustomerController(CustomerService customerService) { - this.customerService = customerService; - } - - // CREATE. - @PostMapping("") - public ResponseEntity createCustomer(@Valid @RequestBody Customer customer) { - // if(bindingResult.hasErrors()) { - // return new ResponseEntity<>(HttpStatus.BAD_REQUEST); - // } - - Customer newCustomer = customerService.createCustomer(customer); - return new ResponseEntity<>(newCustomer, HttpStatus.CREATED); - } - - @PostMapping("/{id}/reviews") - public ResponseEntity addReviewToCustomer(@PathVariable long id, @RequestBody Review review) { - // TODO: process POST request - Review newReview = customerService.addReviewToCustomer(id, review); - return new ResponseEntity<>(newReview, HttpStatus.OK); - } - - // READ (all) - @GetMapping("") - public ResponseEntity> getAllCustomers() { - ArrayList allCustomers = customerService.getAllCustomers(); - return new ResponseEntity<>(allCustomers, HttpStatus.OK); - } - - // READ (id) - @GetMapping("/{id}") - public ResponseEntity getCustomer(@PathVariable long id) { - Customer foundCustomer = customerService.getCustomer(id); - return new ResponseEntity<>(foundCustomer, HttpStatus.OK); - } - - // READ (by name CONTAINS) - @GetMapping("/search") - public ResponseEntity> searchCustomer(@RequestParam String firstName) { - ArrayList customers = customerService.searchCustomer(firstName); - return new ResponseEntity<>(customers, HttpStatus.OK); - } - - // UPDATE - @PutMapping("/{id}") - public ResponseEntity updateCustomer(@PathVariable long id, @RequestBody Customer customer) { - Customer updatedCustomer = customerService.updateCustomer(id, customer); - return new ResponseEntity<>(updatedCustomer, HttpStatus.OK); - } - - // DELETE - @DeleteMapping("/{id}") - public ResponseEntity deleteCustomer(@PathVariable long id) { - customerService.deleteCustomer(id); - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } - - // // Nested route - Add review to customer. - // @PostMapping("/{id}/reviews") - // public ResponseEntity addReviewToCustomer(@PathVariable Long id, - // @Valid @RequestBody Review review) { - // Review newReview = customerService.addReviewToCustomer(id, review); - // return new ResponseEntity<>(newReview, HttpStatus.CREATED); + private CustomerService customerService; + + // @Autowired + public CustomerController(CustomerService customerService) { + this.customerService = customerService; + } + + // CREATE. + @PostMapping("") + public ResponseEntity createCustomer(@Valid @RequestBody Customer customer) { + // if(bindingResult.hasErrors()) { + // return new ResponseEntity<>(HttpStatus.BAD_REQUEST); // } + + Customer newCustomer = customerService.createCustomer(customer); + return new ResponseEntity<>(newCustomer, HttpStatus.CREATED); + } + + @PostMapping("/{id}/products/{productId}/reviews") + public ResponseEntity addReviewToCustomer(@PathVariable long id, @PathVariable long productId, + @RequestBody Review review) { + // TODO: process POST request + Review newReview = customerService.addReviewToCustomer(id, productId, review); + return new ResponseEntity<>(newReview, HttpStatus.OK); + } + + // READ (all) + @GetMapping("") + public ResponseEntity> getAllCustomers() { + ArrayList allCustomers = customerService.getAllCustomers(); + return new ResponseEntity<>(allCustomers, HttpStatus.OK); + } + + // READ (id) + @GetMapping("/{id}") + public ResponseEntity getCustomer(@PathVariable long id) { + Customer foundCustomer = customerService.getCustomer(id); + return new ResponseEntity<>(foundCustomer, HttpStatus.OK); + } + + // READ (by name CONTAINS) + @GetMapping("/search") + public ResponseEntity> searchCustomer(@RequestParam String firstName) { + ArrayList customers = customerService.searchCustomer(firstName); + return new ResponseEntity<>(customers, HttpStatus.OK); + } + + // UPDATE + @PutMapping("/{id}") + public ResponseEntity updateCustomer(@PathVariable long id, @RequestBody Customer customer) { + Customer updatedCustomer = customerService.updateCustomer(id, customer); + return new ResponseEntity<>(updatedCustomer, HttpStatus.OK); + } + + // DELETE + @DeleteMapping("/{id}") + public ResponseEntity deleteCustomer(@PathVariable long id) { + customerService.deleteCustomer(id); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + // // Nested route - Add review to customer. + // @PostMapping("/{id}/reviews") + // public ResponseEntity addReviewToCustomer(@PathVariable Long id, + // @Valid @RequestBody Review review) { + // Review newReview = customerService.addReviewToCustomer(id, review); + // return new ResponseEntity<>(newReview, HttpStatus.CREATED); + // } } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/entities/Customer.java b/src/main/java/sg/com/smartinventory/entities/Customer.java index f10b601..fa50cae 100644 --- a/src/main/java/sg/com/smartinventory/entities/Customer.java +++ b/src/main/java/sg/com/smartinventory/entities/Customer.java @@ -1,5 +1,6 @@ package sg.com.smartinventory.entities; +import java.util.ArrayList; import java.util.List; import jakarta.persistence.CascadeType; @@ -12,7 +13,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToMany; import jakarta.persistence.Table; - +import jakarta.persistence.Transient; import jakarta.validation.constraints.Digits; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; @@ -61,9 +62,25 @@ public class Customer { private String email; @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL) - private List reviews; + @Transient + private List reviewedProducts; + + public List getReviewedProducts() { + if (this.reviews == null) { + return new ArrayList<>(); // return empty list if no reviews + } + + if (reviewedProducts == null) { + reviewedProducts = new ArrayList<>(); + for (Review review : this.reviews) { + reviewedProducts.add(review.getProduct()); + } + } + return reviewedProducts; + } + public Customer() { } diff --git a/src/main/java/sg/com/smartinventory/entities/Product.java b/src/main/java/sg/com/smartinventory/entities/Product.java index fbcde3c..e61c605 100644 --- a/src/main/java/sg/com/smartinventory/entities/Product.java +++ b/src/main/java/sg/com/smartinventory/entities/Product.java @@ -1,18 +1,14 @@ package sg.com.smartinventory.entities; import java.util.List; - import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToMany; import jakarta.persistence.Table; - import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -59,6 +55,9 @@ public class Product { // @JoinColumn(name = "product_id", referencedColumnName = "id") // private List reviews; + // @OneToMany(mappedBy = "product", cascade = CascadeType.ALL) + // private List reviews; + public Product() { } @@ -74,4 +73,5 @@ public Product(String category, String name, String description, double price, i } // @ManyToOne Customer -> Many Products can be linked to 1 Customer + } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/entities/Review.java b/src/main/java/sg/com/smartinventory/entities/Review.java index ab871d5..c41fe53 100644 --- a/src/main/java/sg/com/smartinventory/entities/Review.java +++ b/src/main/java/sg/com/smartinventory/entities/Review.java @@ -3,6 +3,7 @@ import org.springframework.stereotype.Component; import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -44,9 +45,9 @@ public class Review { @Column(name = "rating") private int rating; - // @Min(value = 1, message = "Product ID should start from 1. ") - @Column(name = "product_id") - private long productId; // FK. PostgreSQL bigserial data type. + // // @Min(value = 1, message = "Product ID should start from 1. ") + // @Column(name = "product_id") + // private long productId; // FK. PostgreSQL bigserial data type. // @ManyToOne Customer -> Many Reviews can be linked to 1 Customer // @Min(value = 1, message = "Customer ID should start from 1. ") @@ -56,7 +57,11 @@ public class Review { private Customer customer; // @ManyToOne Product -> Many Reviews can be linked to 1 Product - // TODO + + // @JsonBackReference + @ManyToOne(optional = false) + @JoinColumn(name = "product_id", referencedColumnName = "id") + private Product product; public Review() { } @@ -69,7 +74,7 @@ public Review(String category, String reviewContent, int rating, long customerId this.reviewContent = reviewContent; this.rating = rating; // this.customerId = customerId; - this.productId = productId; + // this.productId = productId; } } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/serviceImpls/CustomerServiceImpl.java b/src/main/java/sg/com/smartinventory/serviceImpls/CustomerServiceImpl.java index 9e5c903..0532533 100644 --- a/src/main/java/sg/com/smartinventory/serviceImpls/CustomerServiceImpl.java +++ b/src/main/java/sg/com/smartinventory/serviceImpls/CustomerServiceImpl.java @@ -6,99 +6,107 @@ import org.springframework.stereotype.Service; import sg.com.smartinventory.entities.Customer; +import sg.com.smartinventory.entities.Product; import sg.com.smartinventory.entities.Review; // import sg.com.smartinventory.entities.Review; import sg.com.smartinventory.exceptions.CustomerNotFoundException; +import sg.com.smartinventory.exceptions.ProductNotFoundException; import sg.com.smartinventory.repositories.CustomerRepository; +import sg.com.smartinventory.repositories.ProductRepository; import sg.com.smartinventory.repositories.ReviewRepository; import sg.com.smartinventory.services.CustomerService; @Service public class CustomerServiceImpl implements CustomerService { - private CustomerRepository customerRepository; - private ReviewRepository reviewRepository; - - // @Autowired - public CustomerServiceImpl(CustomerRepository customerRepository, ReviewRepository reviewRepository) { - this.customerRepository = customerRepository; - this.reviewRepository = reviewRepository; - } - - // - - - POST METHODS - @Override - public Customer createCustomer(Customer customer) { - Customer newCustomer = customerRepository.save(customer); - return newCustomer; - } - - public Review addReviewToCustomer(long id, Review review) { - Customer customer = customerRepository.findById(id).orElseThrow(() -> new CustomerNotFoundException(id)); - review.setCustomer(customer); - Review newReview = reviewRepository.save(review); - return newReview; - } - - // - - - GET METHODS - @Override - public Customer getCustomer(Long id) { - return customerRepository.findById(id).orElseThrow(() -> new CustomerNotFoundException(id)); - } - - @Override - public ArrayList getAllCustomers() { - List allCustomers = customerRepository.findAll(); - return (ArrayList) allCustomers; - } - - // searches for first name that contains search term - @Override - public ArrayList searchCustomer(String firstName) { - List customers = customerRepository.findByFirstNameContaining(firstName); - return (ArrayList) customers; - } - - // - - - PUT METHODS - @Override - public Customer updateCustomer(Long id, Customer customer) { - // Retrieve the customer from the database. - Customer customerToUpdate = customerRepository.findById(id) - .orElseThrow(() -> new CustomerNotFoundException(id)); - - // Update the customer retrieved from the database. - customerToUpdate.setFirstName(customer.getFirstName()); - customerToUpdate.setLastName(customer.getLastName()); - customerToUpdate.setCountry(customer.getCountry()); - customerToUpdate.setAddress(customer.getAddress()); - customerToUpdate.setPostalCode(customer.getPostalCode()); - customerToUpdate.setPhoneNumber(customer.getPhoneNumber()); - customerToUpdate.setEmail(customer.getEmail()); - - // Save the updated customer back to the database. - return customerRepository.save(customerToUpdate); - } - - // - - - DELETE METHODS - @Override - public void deleteCustomer(long id) { - // findById method allows deleteCustomer to throw exception if no id of - // such type is avail to be deleted i.e response will be 404 (Expected) instead - // of 204, to tell client that resource not found - customerRepository.findById(id).orElseThrow(() -> new CustomerNotFoundException(id)); - customerRepository.deleteById(id); - } - - // @Override - // public Review addReviewToCustomer(long customerId, long productId, Review - // review) { - // // retrieve the customer from the database. - // Customer selectedCustomer = - // customerRepository.findById(customerId).orElseThrow(() -> new - // CustomerNotFoundException(customerId)); - - // // add the customer to the review - // review.setCustomer(selectedCustomer); - - // // save the review to the database - // return reviewRepository.save(review); - // } + private ProductRepository productRepository; + private CustomerRepository customerRepository; + private ReviewRepository reviewRepository; + + // @Autowired + public CustomerServiceImpl(CustomerRepository customerRepository, ProductRepository productRepository, + ReviewRepository reviewRepository) { + this.customerRepository = customerRepository; + this.reviewRepository = reviewRepository; + this.productRepository = productRepository; + } + + // - - - POST METHODS + @Override + public Customer createCustomer(Customer customer) { + Customer newCustomer = customerRepository.save(customer); + return newCustomer; + } + + public Review addReviewToCustomer(long id, long productId, Review review) { + Customer customer = customerRepository.findById(id).orElseThrow(() -> new CustomerNotFoundException(id)); + Product product = productRepository.findById(productId).orElseThrow(() -> new ProductNotFoundException(productId)); + review.setCustomer(customer); + review.setProduct(product); + Review newReview = reviewRepository.save(review); + return newReview; + } + + // - - - GET METHODS + @Override + public Customer getCustomer(Long id) { + return customerRepository.findById(id).orElseThrow(() -> new CustomerNotFoundException(id)); + } + + @Override + public ArrayList getAllCustomers() { + List allCustomers = customerRepository.findAll(); + return (ArrayList) allCustomers; + } + + // searches for first name that contains search term + @Override + public ArrayList searchCustomer(String firstName) { + List customers = customerRepository.findByFirstNameContaining(firstName); + return (ArrayList) customers; + } + + // - - - PUT METHODS + @Override + public Customer updateCustomer(Long id, Customer customer) { + // Retrieve the customer from the database. + Customer customerToUpdate = customerRepository.findById(id) + .orElseThrow(() -> new CustomerNotFoundException(id)); + + // Update the customer retrieved from the database. + customerToUpdate.setFirstName(customer.getFirstName()); + customerToUpdate.setLastName(customer.getLastName()); + customerToUpdate.setCountry(customer.getCountry()); + customerToUpdate.setAddress(customer.getAddress()); + customerToUpdate.setPostalCode(customer.getPostalCode()); + customerToUpdate.setPhoneNumber(customer.getPhoneNumber()); + customerToUpdate.setEmail(customer.getEmail()); + + // Save the updated customer back to the database. + return customerRepository.save(customerToUpdate); + } + + // - - - DELETE METHODS + @Override + public void deleteCustomer(long id) { + // findById method allows deleteCustomer to throw exception if no id of + // such type is avail to be deleted i.e response will be 404 (Expected) instead + // of 204, to tell client that resource not found + customerRepository.findById(id).orElseThrow(() -> new CustomerNotFoundException(id)); + customerRepository.deleteById(id); + } + + // @Override + // public Review addReviewToCustomer(long customerId, long productId, Review + // review) { + // // retrieve the customer from the database. + // Customer selectedCustomer = + // customerRepository.findById(customerId).orElseThrow(() -> new + // CustomerNotFoundException(customerId)); + + // // add the customer to the review + // review.setCustomer(selectedCustomer); + + // // save the review to the database + // return reviewRepository.save(review); + // } } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/serviceImpls/ReviewServiceImpl.java b/src/main/java/sg/com/smartinventory/serviceImpls/ReviewServiceImpl.java index 6cb1977..cef7e4b 100644 --- a/src/main/java/sg/com/smartinventory/serviceImpls/ReviewServiceImpl.java +++ b/src/main/java/sg/com/smartinventory/serviceImpls/ReviewServiceImpl.java @@ -14,73 +14,73 @@ @Service public class ReviewServiceImpl implements ReviewService { - private ReviewRepository reviewRepository; - - // @Autowired - public ReviewServiceImpl(ReviewRepository reviewRepository) { - this.reviewRepository = reviewRepository; - } - - // - - - POST - - - - @Override - public Review createReview(Review review) { - Review newReview = reviewRepository.save(review); - - return newReview; - } - - // - - - GET - - - - @Override - public ArrayList searchCustomerReviews(long customerId) { - List foundReviews = reviewRepository.findByCustomerId(customerId); - return (ArrayList) foundReviews; - } - - @Override - public ArrayList searchProductReviews(long productId) { - List foundReviews = reviewRepository.findByProductId(productId); - return (ArrayList) foundReviews; - } - - @Override - public ArrayList getRatings(int id) { - if (reviewRepository.findByRating(id).isEmpty()) { - throw new RatingNotFoundException(id); - } - List reviews = reviewRepository.findByRating(id); - return (ArrayList) reviews; - } - - @Override - public Review getReview(Long id) { - return reviewRepository.findById(id).orElseThrow(() -> new ReviewNotFoundException(id)); - } - - @Override - public ArrayList getAllReviews() { - List allReviews = reviewRepository.findAll(); - return (ArrayList) allReviews; - } - - // - - - PUT - - - - @Override - public Review updateReview(Long id, Review review) { - // Retrieve the review from the database. - Review reviewToUpdate = reviewRepository.findById(id).orElseThrow(() -> new ReviewNotFoundException(id)); - - // Update the review retrieved from the database. - reviewToUpdate.setCategory(review.getCategory()); - reviewToUpdate.setReviewContent(review.getReviewContent()); - reviewToUpdate.setRating(review.getRating()); - reviewToUpdate.setProductId(review.getProductId()); - - // Save the updated review back to the database. - return reviewRepository.save(reviewToUpdate); - } - - // - - - DELETE - - - - @Override - public void deleteReview(long id) { - reviewRepository.deleteById(id); + private ReviewRepository reviewRepository; + + // @Autowired + public ReviewServiceImpl(ReviewRepository reviewRepository) { + this.reviewRepository = reviewRepository; + } + + // - - - POST - - - + @Override + public Review createReview(Review review) { + Review newReview = reviewRepository.save(review); + + return newReview; + } + + // - - - GET - - - + @Override + public ArrayList searchCustomerReviews(long customerId) { + List foundReviews = reviewRepository.findByCustomerId(customerId); + return (ArrayList) foundReviews; + } + + @Override + public ArrayList searchProductReviews(long productId) { + List foundReviews = reviewRepository.findByProductId(productId); + return (ArrayList) foundReviews; + } + + @Override + public ArrayList getRatings(int id) { + if (reviewRepository.findByRating(id).isEmpty()) { + throw new RatingNotFoundException(id); } + List reviews = reviewRepository.findByRating(id); + return (ArrayList) reviews; + } + + @Override + public Review getReview(Long id) { + return reviewRepository.findById(id).orElseThrow(() -> new ReviewNotFoundException(id)); + } + + @Override + public ArrayList getAllReviews() { + List allReviews = reviewRepository.findAll(); + return (ArrayList) allReviews; + } + + // - - - PUT - - - + @Override + public Review updateReview(Long id, Review review) { + // Retrieve the review from the database. + Review reviewToUpdate = reviewRepository.findById(id).orElseThrow(() -> new ReviewNotFoundException(id)); + + // Update the review retrieved from the database. + reviewToUpdate.setCategory(review.getCategory()); + reviewToUpdate.setReviewContent(review.getReviewContent()); + reviewToUpdate.setRating(review.getRating()); + reviewToUpdate.setProduct(review.getProduct()); + + // Save the updated review back to the database. + return reviewRepository.save(reviewToUpdate); + } + + // - - - DELETE - - - + @Override + public void deleteReview(long id) { + reviewRepository.deleteById(id); + } } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/services/CustomerService.java b/src/main/java/sg/com/smartinventory/services/CustomerService.java index 59bff4a..aa28f52 100644 --- a/src/main/java/sg/com/smartinventory/services/CustomerService.java +++ b/src/main/java/sg/com/smartinventory/services/CustomerService.java @@ -7,19 +7,20 @@ import sg.com.smartinventory.entities.Review; public interface CustomerService { - Customer createCustomer(Customer customer); + Customer createCustomer(Customer customer); - Review addReviewToCustomer(long id, Review review); + // Review addReviewToCustomer(long id, Review review); - Customer getCustomer(Long id); + Customer getCustomer(Long id); - ArrayList searchCustomer(String name); + ArrayList searchCustomer(String name); - ArrayList getAllCustomers(); + ArrayList getAllCustomers(); - Customer updateCustomer(Long id, Customer customer); + Customer updateCustomer(Long id, Customer customer); - void deleteCustomer(long id); + void deleteCustomer(long id); - // Review addReviewToCustomer(long customerId, long productId, Review review); + Review addReviewToCustomer(long id, long productId, Review review); + // Review addReviewToCustomer(long customerId, long productId, Review review); } \ No newline at end of file diff --git a/src/main/java/sg/com/smartinventory/utility/DataLoader.java b/src/main/java/sg/com/smartinventory/utility/DataLoader.java index be49e14..542afcb 100644 --- a/src/main/java/sg/com/smartinventory/utility/DataLoader.java +++ b/src/main/java/sg/com/smartinventory/utility/DataLoader.java @@ -14,127 +14,136 @@ @Component public class DataLoader { - // Inject all repositories. - private CustomerRepository customerRepository; - private ProductRepository productRepository; - private ReviewRepository reviewRepository; - private Review review; - - // @Autowired - public DataLoader(CustomerRepository customerRepository, ProductRepository productRepository, - ReviewRepository reviewRepository, Review review) { - this.customerRepository = customerRepository; - this.productRepository = productRepository; - this.reviewRepository = reviewRepository; - this.review = review; - } - - @PostConstruct - public void loadData() { - // // Clear all data. - // clearTableData(); - - // // Create fake data. - // generateFakeData(); - // } - - // public void clearTableData() { - // Clear all data. - customerRepository.deleteAll(); - productRepository.deleteAll(); - reviewRepository.deleteAll(); - // } - - // <<<<<<< SIS-39 - // = = = CUSTOMER DATA = = = - Customer customer1 = customerRepository - .save(new Customer("John", "Doe", "USA", "123 Main St", 123456, 12345678, - "john.doe@example.com")); - Customer customer2 = customerRepository - .save(new Customer("Alice", "Smith", "Canada", "456 Maple Ave", 543210, 98765432, - "alice.smith@example.com")); - Customer customer3 = customerRepository - .save(new Customer("Michael", "Johnson", "UK", "789 Oak Rd", 567890, 98761234, - "michael.johnson@example.com")); - Customer customer4 = customerRepository - .save(new Customer("Emily", "Brown", "Australia", "321 Elm St", 135790, 45678912, - "emily.brown@example.com")); - Customer customer5 = customerRepository - .save(new Customer("David", "Wilson", "Germany", "654 Pine Rd", 987655, 36985214, - "david.wilson@example.com")); - // ======= - // public void generateFakeData() { - // // Create fake data. - // customerRepository.save(new Customer("John", "Doe", "USA", "123 Main St", - // 123456, 12345678, - // "john.doe@example.com")); - // customerRepository.save(new Customer("Alice", "Smith", "Canada", "456 Maple - // Ave", 543210, 98765432, - // "alice.smith@example.com")); - // customerRepository.save(new Customer("Michael", "Johnson", "UK", "789 Oak - // Rd", 567890, 98761234, - // "michael.johnson@example.com")); - // customerRepository.save(new Customer("Emily", "Brown", "Australia", "321 Elm - // St", 135790, 45678912, - // "emily.brown@example.com")); - // customerRepository.save(new Customer("David", "Wilson", "Germany", "654 Pine - // Rd", 987655, 36985214, - // "david.wilson@example.com")); - // >>>>>>> main - - // = = = REVIEW DATA = = = - // Adding review data (note that the "same" review object is being used in all, - // this is because of Bean injection so its actually diff instances) - Review review = new Review("Books", "Expected more from the ending, felt rushed. ", 3, 1, 1); - review.setCustomer(customer1); - reviewRepository.save(review); - - review = new Review("Electronics", "Fast delivery, product works as expected. ", 4, 1, 2); - review.setCustomer(customer2); - reviewRepository.save(review); - - review = new Review("Home & Kitchen", "Difficult to assemble, but sturdy once done. ", 3, 2, 4); - review.setCustomer(customer3); - reviewRepository.save(review); - - review = new Review("Electronics", "Great smartphone with excellent features. ", 5, 3, 1); - review.setCustomer(customer4); - reviewRepository.save(review); - - review = new Review("Clothing", "The color faded after a few washes. ", 2, 3, 3); - review.setCustomer(customer5); - reviewRepository.save(review); - - review = (new Review("Beauty", "Lovely fragrance, long-lasting. ", 5, 4, 4)); - review.setCustomer(customer1); - reviewRepository.save(review); - - review = (new Review("Home & Kitchen", "Makes delicious coffee, easy to use. ", 4, 4, 3)); - review.setCustomer(customer2); - reviewRepository.save(review); - - review = (new Review("Books", "Intriguing plot, couldn't put it down. ", 5, 5, 5)); - review.setCustomer(customer3); - reviewRepository.save(review); - - review = (new Review("Beauty", "Disappointed with the scent, doesn't last long. ", 2, 5, 5)); - review.setCustomer(customer4); - reviewRepository.save(review); - - // = = = PRODUCT = = = - productRepository.save(new Product("Electronics", "Smartphone", - "High-end smartphone with advanced features. ", 999.99, 100)); - productRepository.save(new Product("Clothing", "Men's T-Shirt", - "Comfortable cotton t-shirt for everyday wear. ", 29.99, 500)); - productRepository.save(new Product("Home & Kitchen", "Coffee Maker", - "Automatic coffee maker with programmable settings. ", 49.99, 50)); - productRepository.save(new Product("Beauty", "Perfume", - "Elegant fragrance with floral and citrus notes. ", 79.99, 200)); - productRepository.save(new Product("Books", "Science Fiction Novel", - "Bestselling sci-fi novel set in a dystopian future. ", 14.99, 300)); - - // = = = NOTE: DATALOADER DONT WORK FOR ENTITIES WITH FK* (cant specify - // customer_id column) = = = - - } + // Inject all repositories. + private CustomerRepository customerRepository; + private ProductRepository productRepository; + private ReviewRepository reviewRepository; + private Review review; + + // @Autowired + public DataLoader(CustomerRepository customerRepository, ProductRepository productRepository, + ReviewRepository reviewRepository, Review review) { + this.customerRepository = customerRepository; + this.productRepository = productRepository; + this.reviewRepository = reviewRepository; + this.review = review; + } + + @PostConstruct + public void loadData() { + // // Clear all data. + // clearTableData(); + + // // Create fake data. + // generateFakeData(); + // } + + // public void clearTableData() { + // Clear all data. + customerRepository.deleteAll(); + productRepository.deleteAll(); + reviewRepository.deleteAll(); + // } + + // <<<<<<< SIS-39 + // = = = CUSTOMER DATA = = = + Customer customer1 = customerRepository + .save(new Customer("John", "Doe", "USA", "123 Main St", 123456, 12345678, + "john.doe@example.com")); + Customer customer2 = customerRepository + .save(new Customer("Alice", "Smith", "Canada", "456 Maple Ave", 543210, 98765432, + "alice.smith@example.com")); + Customer customer3 = customerRepository + .save(new Customer("Michael", "Johnson", "UK", "789 Oak Rd", 567890, 98761234, + "michael.johnson@example.com")); + Customer customer4 = customerRepository + .save(new Customer("Emily", "Brown", "Australia", "321 Elm St", 135790, 45678912, + "emily.brown@example.com")); + Customer customer5 = customerRepository + .save(new Customer("David", "Wilson", "Germany", "654 Pine Rd", 987655, 36985214, + "david.wilson@example.com")); + // ======= + // public void generateFakeData() { + // // Create fake data. + // customerRepository.save(new Customer("John", "Doe", "USA", "123 Main St", + // 123456, 12345678, + // "john.doe@example.com")); + // customerRepository.save(new Customer("Alice", "Smith", "Canada", "456 Maple + // Ave", 543210, 98765432, + // "alice.smith@example.com")); + // customerRepository.save(new Customer("Michael", "Johnson", "UK", "789 Oak + // Rd", 567890, 98761234, + // "michael.johnson@example.com")); + // customerRepository.save(new Customer("Emily", "Brown", "Australia", "321 Elm + // St", 135790, 45678912, + // "emily.brown@example.com")); + // customerRepository.save(new Customer("David", "Wilson", "Germany", "654 Pine + // Rd", 987655, 36985214, + // "david.wilson@example.com")); + // >>>>>>> main + + // = = = PRODUCT = = = + Product product1 = productRepository.save(new Product("Electronics", "Smartphone", + "High-end smartphone with advanced features. ", 999.99, 100)); + Product product2 = productRepository.save(new Product("Clothing", "Men's T-Shirt", + "Comfortable cotton t-shirt for everyday wear. ", 29.99, 500)); + Product product3 = productRepository.save(new Product("Home & Kitchen", "Coffee Maker", + "Automatic coffee maker with programmable settings. ", 49.99, 50)); + Product product4 = productRepository.save(new Product("Beauty", "Perfume", + "Elegant fragrance with floral and citrus notes. ", 79.99, 200)); + Product product5 = productRepository.save(new Product("Books", "Science Fiction Novel", + "Bestselling sci-fi novel set in a dystopian future. ", 14.99, 300)); + + // = = = REVIEW DATA = = = + // Adding review data (note that the "same" review object is being used in all, + // this is because of Bean injection so its actually diff instances) + Review review = new Review("Books", "Expected more from the ending, felt rushed. ", 3, 1, 5); + review.setCustomer(customer1); + review.setProduct(product5); + reviewRepository.save(review); + + review = new Review("Electronics", "Fast delivery, product works as expected. ", 4, 1, 1); + review.setCustomer(customer2); + review.setProduct(product1); + reviewRepository.save(review); + + review = new Review("Home & Kitchen", "Difficult to assemble, but sturdy once done. ", 3, 2, 3); + review.setCustomer(customer3); + review.setProduct(product3); + reviewRepository.save(review); + + review = new Review("Electronics", "Great smartphone with excellent features. ", 5, 3, 1); + review.setCustomer(customer4); + review.setProduct(product1); + reviewRepository.save(review); + + review = new Review("Clothing", "The color faded after a few washes. ", 2, 3, 2); + review.setCustomer(customer5); + review.setProduct(product2); + reviewRepository.save(review); + + review = (new Review("Beauty", "Lovely fragrance, long-lasting. ", 5, 4, 4)); + review.setCustomer(customer1); + review.setProduct(product4); + reviewRepository.save(review); + + review = (new Review("Home & Kitchen", "Makes delicious coffee, easy to use. ", 4, 4, 3)); + review.setCustomer(customer2); + review.setProduct(product3); + reviewRepository.save(review); + + review = (new Review("Books", "Intriguing plot, couldn't put it down. ", 5, 5, 5)); + review.setCustomer(customer3); + review.setProduct(product5); + reviewRepository.save(review); + + review = (new Review("Beauty", "Disappointed with the scent, doesn't last long. ", 2, 5, 4)); + review.setCustomer(customer4); + review.setProduct(product4); + reviewRepository.save(review); + + // = = = NOTE: DATALOADER DONT WORK FOR ENTITIES WITH FK* (cant specify + // customer_id column) = = = + + } } \ No newline at end of file diff --git a/src/test/java/sg/com/smartinventory/services/ReviewServiceImplTest.java b/src/test/java/sg/com/smartinventory/services/ReviewServiceImplTest.java index 6d38c1d..fa6696a 100644 --- a/src/test/java/sg/com/smartinventory/services/ReviewServiceImplTest.java +++ b/src/test/java/sg/com/smartinventory/services/ReviewServiceImplTest.java @@ -28,61 +28,60 @@ @SpringBootTest public class ReviewServiceImplTest { - @Mock - private ReviewRepository reviewRepository; + @Mock + private ReviewRepository reviewRepository; - @InjectMocks - ReviewServiceImpl reviewService; + @InjectMocks + ReviewServiceImpl reviewService; - /// Name this according to your class name. - // The Logback library defines 5 log levels in order of priority: TRACE, DEBUG, - // INFO, WARN, ERROR, with each of these having a corresponding logging method: - // trace(), debug(), info(), warn(), error(). - private static final Logger test_logger = LoggerFactory.getLogger(ReviewServiceImplTest.class); + /// Name this according to your class name. + // The Logback library defines 5 log levels in order of priority: TRACE, DEBUG, + // INFO, WARN, ERROR, with each of these having a corresponding logging method: + // trace(), debug(), info(), warn(), error(). + private static final Logger test_logger = LoggerFactory.getLogger(ReviewServiceImplTest.class); - // Test Setup and Teardown configuration. - @BeforeAll - static void initAll() { + // Test Setup and Teardown configuration. + @BeforeAll + static void initAll() { - } + } - @AfterAll - static void teardownAll() { + @AfterAll + static void teardownAll() { - } + } - @BeforeEach - void init() { + @BeforeEach + void init() { - } + } - @AfterEach - void teardown() { + @AfterEach + void teardown() { - } + } - @Test - public void createReviewTest() { - test_logger.info("Starting test: " + getCurrentMethodName() + ". "); + @Test + public void createReviewTest() { + test_logger.info("Starting test: " + getCurrentMethodName() + ". "); - // 1. SETUP. - // Create a new review. - Review review = Review.builder().category("Electronics") - .reviewContent("Great smartphone with excellent features. ").rating(5) - .productId(2).build(); + // 1. SETUP. + // Create a new review. + Review review = Review.builder().category("Electronics").reviewContent("Great smartphone with excellent features. ") + .rating(5).build(); - // Mock the save method of the review repository. - when((reviewRepository.save(review))).thenReturn(review); + // Mock the save method of the review repository. + when((reviewRepository.save(review))).thenReturn(review); - // 2. EXECUTE. - Review savedReview = reviewService.createReview(review); + // 2. EXECUTE. + Review savedReview = reviewService.createReview(review); - // 3. ASSERT. - assertEquals(review, savedReview, "The saved review should be the same as the new review created. "); + // 3. ASSERT. + assertEquals(review, savedReview, "The saved review should be the same as the new review created. "); - // Verify that the save method of the review repository is called once only. - verify(reviewRepository, times(1)).save(review); + // Verify that the save method of the review repository is called once only. + verify(reviewRepository, times(1)).save(review); - test_logger.info("Ending test: " + getCurrentMethodName() + ". "); - } + test_logger.info("Ending test: " + getCurrentMethodName() + ". "); + } } \ No newline at end of file