Skip to content

Commit 2bc6a43

Browse files
hospelAudriusPutys
andauthored
V1.0.0 preview.1: Merge V1.0.0 preview.1 merge into main branch (#112)
* BENCH-255 category response implemented and product request updated * Bench-255 conflict resolved * split unit and integration tests (#110) * adjust delete as per API contract (#111) Co-authored-by: AudriusPutys <Audrius.Putys@answerdigital.com> Co-authored-by: AudriusPutys <116072957+AudriusPutys@users.noreply.github.com>
1 parent 3e5cb55 commit 2bc6a43

File tree

19 files changed

+186
-142
lines changed

19 files changed

+186
-142
lines changed

pom.xml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,4 +236,40 @@
236236
</plugins>
237237
</build>
238238

239+
<profiles>
240+
<profile>
241+
<id>unit-test</id>
242+
<build>
243+
<plugins>
244+
<plugin>
245+
<groupId>org.apache.maven.plugins</groupId>
246+
<artifactId>maven-surefire-plugin</artifactId>
247+
<configuration>
248+
<includes>
249+
<include>**/*Test.java</include>
250+
</includes>
251+
</configuration>
252+
</plugin>
253+
</plugins>
254+
</build>
255+
</profile>
256+
<profile>
257+
<id>integration-test</id>
258+
<build>
259+
<plugins>
260+
<plugin>
261+
<groupId>org.apache.maven.plugins</groupId>
262+
<artifactId>maven-surefire-plugin</artifactId>
263+
<configuration>
264+
<includes>
265+
<include>**/*IntegrationTests.java</include>
266+
</includes>
267+
</configuration>
268+
</plugin>
269+
</plugins>
270+
</build>
271+
</profile>
272+
273+
</profiles>
274+
239275
</project>
Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.answerdigital.answerking.controller;
22

33
import com.answerdigital.answerking.exception.util.ErrorResponse;
4-
import com.answerdigital.answerking.model.Category;
54
import com.answerdigital.answerking.request.CategoryRequest;
65
import com.answerdigital.answerking.response.CategoryResponse;
76
import com.answerdigital.answerking.response.ProductResponse;
@@ -16,14 +15,14 @@
1615
import org.springframework.http.HttpStatus;
1716
import org.springframework.http.ResponseEntity;
1817
import org.springframework.validation.annotation.Validated;
18+
import org.springframework.web.bind.annotation.DeleteMapping;
19+
import org.springframework.web.bind.annotation.GetMapping;
1920
import org.springframework.web.bind.annotation.PathVariable;
21+
import org.springframework.web.bind.annotation.PostMapping;
22+
import org.springframework.web.bind.annotation.PutMapping;
2023
import org.springframework.web.bind.annotation.RequestBody;
2124
import org.springframework.web.bind.annotation.RequestMapping;
2225
import org.springframework.web.bind.annotation.RestController;
23-
import org.springframework.web.bind.annotation.GetMapping;
24-
import org.springframework.web.bind.annotation.PostMapping;
25-
import org.springframework.web.bind.annotation.PutMapping;
26-
import org.springframework.web.bind.annotation.DeleteMapping;
2726

2827
import javax.validation.Valid;
2928
import javax.validation.constraints.NotNull;
@@ -45,9 +44,9 @@ public CategoryController(final CategoryService categoryService) {
4544
@Operation(summary = "Create a new category.")
4645
@ApiResponses(value = {
4746
@ApiResponse(responseCode = "201", description = "When the category has been created.",
48-
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = Category.class)) }),
47+
content = {@Content(mediaType = "application/json", schema = @Schema(implementation = CategoryResponse.class))}),
4948
@ApiResponse(responseCode = "400", description = "When invalid parameters are provided.",
50-
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)) })
49+
content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class))})
5150
})
5251
@PostMapping
5352
public ResponseEntity<CategoryResponse> addCategory(@Valid @RequestBody final CategoryRequest categoryRequest) {
@@ -57,7 +56,7 @@ public ResponseEntity<CategoryResponse> addCategory(@Valid @RequestBody final Ca
5756
@Operation(summary = "Get all categories.")
5857
@ApiResponses(value = {
5958
@ApiResponse(responseCode = "200", description = "Found the list of categories.",
60-
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = Category.class)) })
59+
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = CategoryResponse.class)) })
6160
})
6261
@GetMapping
6362
public ResponseEntity<Collection<CategoryResponse>> getAllCategories() {
@@ -68,21 +67,21 @@ public ResponseEntity<Collection<CategoryResponse>> getAllCategories() {
6867
@Operation(summary = "Get a single category.")
6968
@ApiResponses(value = {
7069
@ApiResponse(responseCode = "200", description = "When the category with the provided id has been found.",
71-
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = Category.class)) }),
70+
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = CategoryResponse.class)) }),
7271
@ApiResponse(responseCode = "404", description = "When the category with the given id does not exist.",
73-
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)) })
72+
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)) })
7473
})
7574
@GetMapping("/{categoryId}")
76-
public ResponseEntity<Category> getCategoryById(@PathVariable @NotNull final Long categoryId) {
77-
return new ResponseEntity<>(categoryService.findById(categoryId), HttpStatus.OK);
75+
public ResponseEntity<CategoryResponse> getCategoryById(@PathVariable @NotNull final Long categoryId) {
76+
return new ResponseEntity<>(categoryService.findByIdResponse(categoryId), HttpStatus.OK);
7877
}
7978

8079
@Operation(summary = "Get all products in a category.")
8180
@ApiResponses(value = {
8281
@ApiResponse(responseCode = "200", description = "When all the products have been returned.",
83-
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = Category.class)) }),
82+
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = CategoryResponse.class)) }),
8483
@ApiResponse(responseCode = "404", description = "When the category with the given id does not exist.",
85-
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)) })
84+
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)) })
8685
})
8786
@GetMapping("/{categoryId}/products")
8887
public ResponseEntity<Collection<ProductResponse>> fetchProductsByCategory(@PathVariable @NotNull final Long categoryId) {
@@ -92,53 +91,54 @@ public ResponseEntity<Collection<ProductResponse>> fetchProductsByCategory(@Path
9291
@Operation(summary = "Add product to a category.")
9392
@ApiResponses(value = {
9493
@ApiResponse(responseCode = "200", description = "Add product to a category.",
95-
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = Category.class)) })
94+
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = CategoryResponse.class)) })
9695
})
9796
@PutMapping("/{categoryId}/addproduct/{productId}")
98-
public ResponseEntity<Category> addProductToCategory(@PathVariable @NotNull final Long categoryId,
97+
public ResponseEntity<CategoryResponse> addProductToCategory(@PathVariable @NotNull final Long categoryId,
9998
@PathVariable @NotNull final Long productId) {
10099
return new ResponseEntity<>(categoryService.addProductToCategory(categoryId, productId), HttpStatus.OK);
101100
}
102101

103102
@Operation(summary = "Remove product from a category.")
104103
@ApiResponses(value = {
105104
@ApiResponse(responseCode = "200", description = "Remove product from a category.",
106-
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = Category.class)) })
105+
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = CategoryResponse.class)) })
107106
})
108107
@PutMapping("/{categoryId}/removeproduct/{productId}")
109-
public ResponseEntity<Category> removeProductFromCategory(@PathVariable @NotNull final Long categoryId,
108+
public ResponseEntity<CategoryResponse> removeProductFromCategory(@PathVariable @NotNull final Long categoryId,
110109
@PathVariable @NotNull final Long productId) {
111110
return new ResponseEntity<>(categoryService.removeProductFromCategory(categoryId, productId), HttpStatus.OK);
112111
}
113112

114113
@Operation(summary = "Update an existing category.")
115114
@ApiResponses(value = {
116115
@ApiResponse(responseCode = "200", description = "When the category has been updated.",
117-
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = Category.class)) }),
116+
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = CategoryResponse.class)) }),
118117
@ApiResponse(responseCode = "400", description = "When invalid parameters are provided.",
119-
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)) }),
118+
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)) }),
120119
@ApiResponse(responseCode = "404", description = "When the category with the given id does not exist.",
121-
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)) })
120+
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)) })
122121
})
123122
@PutMapping("/{categoryId}")
124-
public ResponseEntity<Category> updateCategory(@Valid @RequestBody final CategoryRequest categoryRequest,
123+
public ResponseEntity<CategoryResponse> updateCategory(@Valid @RequestBody final CategoryRequest categoryRequest,
125124
@PathVariable @NotNull final Long categoryId) {
126125
return new ResponseEntity<>(categoryService.updateCategory(categoryRequest, categoryId), HttpStatus.OK);
127126
}
128127

129128
@Operation(summary = "Retire an existing category.")
130129
@ApiResponses(value = {
131130
@ApiResponse(responseCode = "200", description = "When the category has been retired.",
132-
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = Category.class)) }),
131+
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = CategoryResponse.class)) }),
133132
@ApiResponse(responseCode = "400", description = "When invalid parameters are provided.",
134-
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)) }),
133+
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)) }),
135134
@ApiResponse(responseCode = "404", description = "When the category with the given id does not exist.",
136-
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)) }),
135+
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)) }),
137136
@ApiResponse(responseCode = "410", description = "When the category with the given id is already retired.",
138-
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)) })
137+
content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)) })
139138
})
140139
@DeleteMapping("/{categoryId}")
141-
public ResponseEntity<Category> retireCategory(@PathVariable @NotNull final Long categoryId) {
142-
return new ResponseEntity<>(categoryService.retireCategory(categoryId), HttpStatus.OK);
140+
public ResponseEntity<Void> retireCategory(@PathVariable @NotNull final Long categoryId) {
141+
categoryService.retireCategory(categoryId);
142+
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
143143
}
144144
}

src/main/java/com/answerdigital/answerking/controller/OrderController.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,10 @@ public ResponseEntity<Order> addProductToBasket(@PathVariable @NotNull final Lon
6464
}
6565

6666
@DeleteMapping(path = "/{orderId}/product/{productId}")
67-
public ResponseEntity<Order> deleteProductInBasket(@PathVariable @NotNull final Long orderId,
67+
public ResponseEntity<Void> deleteProductInBasket(@PathVariable @NotNull final Long orderId,
6868
@PathVariable @NotNull final Long productId) {
69-
return new ResponseEntity<>(orderService.deleteProductInBasket(orderId, productId), HttpStatus.OK);
69+
orderService.deleteProductInBasket(orderId, productId);
70+
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
7071
}
7172

7273
@PutMapping(path = "/{orderId}/product/{productId}/quantity/{quantity}")

src/main/java/com/answerdigital/answerking/controller/ProductController.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ public ResponseEntity<ProductResponse> updateProduct(@PathVariable @NotNull fina
105105
schema = @Schema(implementation = ErrorResponse.class)) })
106106
})
107107
@DeleteMapping("/{id}")
108-
public ResponseEntity<ProductResponse> retireProduct(@PathVariable @NotNull final Long id) {
109-
return new ResponseEntity<>(productService.retireProduct(id), HttpStatus.OK);
108+
public ResponseEntity<Void> retireProduct(@PathVariable @NotNull final Long id) {
109+
productService.retireProduct(id);
110+
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
110111
}
111112
}

src/main/java/com/answerdigital/answerking/mapper/CategoryMapper.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
@Mapper(componentModel = "spring",
1414
imports = {Collectors.class, Collections.class})
1515
public interface CategoryMapper {
16+
1617
@Mapping(target = "products", expression = "java(Collections.EMPTY_SET)")
1718
Category addRequestToCategory(CategoryRequest addCategoryRequest);
1819

src/main/java/com/answerdigital/answerking/mapper/ProductMapper.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,19 @@
66
import org.mapstruct.Mapper;
77
import org.mapstruct.Mapping;
88
import org.mapstruct.MappingTarget;
9+
910
import java.util.List;
11+
import java.util.stream.Collectors;
1012

11-
@Mapper(componentModel = "spring", imports = {List.class})
13+
@Mapper(componentModel = "spring", imports = {List.class, Collectors.class})
1214
public interface ProductMapper {
1315
@Mapping(target = "retired", constant = "false")
1416
Product addRequestToProduct(ProductRequest productRequest);
1517

1618
Product updateRequestToProduct(@MappingTarget Product product, ProductRequest productRequest);
1719

18-
@Mapping(target = "categories", expression = "java(List.of(product.getCategory().getId()))")
20+
@Mapping(target = "category.products",
21+
expression = "java(category.getProducts().stream().map(product -> product.getId()).collect(Collectors.toList()) )")
1922
ProductResponse convertProductEntityToProductResponse(Product product);
2023

2124
}

src/main/java/com/answerdigital/answerking/model/Category.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.answerdigital.answerking.model;
22

3-
import com.fasterxml.jackson.annotation.JsonIgnore;
43
import lombok.AccessLevel;
54
import lombok.AllArgsConstructor;
65
import lombok.Builder;
@@ -56,7 +55,6 @@ public class Category {
5655
private boolean retired;
5756

5857
@OneToMany(mappedBy="category", fetch = FetchType.EAGER)
59-
@JsonIgnore
6058
private Set<Product> products = new HashSet<>();
6159

6260
public Category(final String name, final String description) {

src/main/java/com/answerdigital/answerking/request/ProductRequest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ public record ProductRequest(
2222
@Digits(integer = 12, fraction = 2, message = "Product price is invalid")
2323
@DecimalMin(value = "0.0", inclusive = false, message = "Product price cannot be less than 0")
2424
@NotNull
25-
BigDecimal price
25+
BigDecimal price,
26+
@NotNull
27+
Long categoryId
2628
) {
2729
@Builder
2830
public ProductRequest {

src/main/java/com/answerdigital/answerking/response/CategoryResponse.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,12 @@ public class CategoryResponse {
2222

2323
private String description;
2424

25-
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
2625
private List<Long> products;
2726

28-
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
2927
private LocalDateTime createdOn;
3028

31-
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
3229
private LocalDateTime lastUpdated;
3330

34-
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
3531
private boolean retired;
3632

3733
}

src/main/java/com/answerdigital/answerking/response/ProductResponse.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import lombok.NoArgsConstructor;
77

88
import java.math.BigDecimal;
9-
import java.util.List;
109

1110
@Data
1211
@Builder
@@ -22,7 +21,7 @@ public class ProductResponse {
2221

2322
private BigDecimal price;
2423

25-
private List<Long> categories;
24+
private CategoryResponse category;
2625

2726
private boolean retired;
2827
}

0 commit comments

Comments
 (0)