Skip to content

Commit cac7a9a

Browse files
authored
Merge pull request #8 from companieshouse/PCI-608-clear-basket
Clear basket once payment has been patched
2 parents bc80f47 + c68f000 commit cac7a9a

File tree

9 files changed

+157
-5
lines changed

9 files changed

+157
-5
lines changed

src/main/java/uk/gov/companieshouse/orders/api/controller/BasketController.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import uk.gov.companieshouse.orders.api.model.Basket;
2020
import uk.gov.companieshouse.orders.api.model.Checkout;
2121
import uk.gov.companieshouse.orders.api.model.Item;
22+
import uk.gov.companieshouse.orders.api.model.PaymentStatus;
2223
import uk.gov.companieshouse.orders.api.service.ApiClientService;
2324
import uk.gov.companieshouse.orders.api.service.BasketService;
2425
import uk.gov.companieshouse.orders.api.service.CheckoutService;
@@ -122,8 +123,13 @@ public ResponseEntity<?> checkoutBasket(@RequestBody(required = false) String js
122123
@PatchMapping("${uk.gov.companieshouse.orders.api.basket.payment}/{id}")
123124
public ResponseEntity<String> patchBasketPaymentDetails(final @RequestBody BasketPaymentRequestDTO basketPaymentRequestDTO,
124125
final @PathVariable String id,
126+
HttpServletRequest request,
125127
final @RequestHeader(REQUEST_ID_HEADER_NAME) String requestId) {
126128
trace("ENTERING patchBasketPaymentDetails(" + basketPaymentRequestDTO + ", " + id + ", " + requestId + ")", requestId);
129+
if(basketPaymentRequestDTO.getStatus().equals(PaymentStatus.PAID)) {
130+
Basket basket = basketService.clearBasket(EricHeaderHelper.getIdentity(request));
131+
trace("Cleared basket: " + basket, requestId);
132+
}
127133
return ResponseEntity.ok("");
128134
}
129135

src/main/java/uk/gov/companieshouse/orders/api/dto/BasketPaymentRequestDTO.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package uk.gov.companieshouse.orders.api.dto;
22

33
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import uk.gov.companieshouse.orders.api.model.PaymentStatus;
45

56
public class BasketPaymentRequestDTO {
67

@@ -11,7 +12,7 @@ public class BasketPaymentRequestDTO {
1112
private String paymentReference;
1213

1314
@JsonProperty("status")
14-
private String status;
15+
private PaymentStatus status;
1516

1617
public String getPaidAt() {
1718
return paidAt;
@@ -29,11 +30,11 @@ public void setPaymentReference(String paymentReference) {
2930
this.paymentReference = paymentReference;
3031
}
3132

32-
public String getStatus() {
33+
public PaymentStatus getStatus() {
3334
return status;
3435
}
3536

36-
public void setStatus(String status) {
37+
public void setStatus(PaymentStatus status) {
3738
this.status = status;
3839
}
3940
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package uk.gov.companieshouse.orders.api.model;
2+
3+
import com.fasterxml.jackson.annotation.JsonValue;
4+
5+
import static uk.gov.companieshouse.orders.api.converter.EnumValueNameConverter.convertEnumValueNameToJson;
6+
7+
public enum PaymentStatus {
8+
PAID,
9+
FAILED,
10+
PENDING,
11+
EXPIRED,
12+
IN_PROGRESS,
13+
NO_FUNDS;
14+
15+
@JsonValue
16+
public String getJsonName() {
17+
return convertEnumValueNameToJson(this);
18+
}
19+
}

src/main/java/uk/gov/companieshouse/orders/api/repository/BasketRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
import uk.gov.companieshouse.orders.api.model.Basket;
66

77
@RepositoryRestResource
8-
public interface BasketRepository extends MongoRepository<Basket, String> { }
8+
public interface BasketRepository extends MongoRepository<Basket, String>, BasketRepositoryCustom { }
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package uk.gov.companieshouse.orders.api.repository;
2+
3+
import uk.gov.companieshouse.orders.api.model.Basket;
4+
5+
public interface BasketRepositoryCustom {
6+
Basket clearBasketDataById(String id);
7+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package uk.gov.companieshouse.orders.api.repository;
2+
3+
import org.springframework.data.mongodb.core.MongoTemplate;
4+
import org.springframework.data.mongodb.core.query.Query;
5+
import org.springframework.data.mongodb.core.query.Update;
6+
import uk.gov.companieshouse.orders.api.model.Basket;
7+
import uk.gov.companieshouse.orders.api.model.BasketData;
8+
9+
import static org.springframework.data.mongodb.core.query.Criteria.where;
10+
11+
12+
public class BasketRepositoryImpl implements BasketRepositoryCustom {
13+
14+
private final MongoTemplate mongoTemplate;
15+
16+
public BasketRepositoryImpl(MongoTemplate mongoTemplate) {
17+
this.mongoTemplate = mongoTemplate;
18+
}
19+
20+
@Override
21+
public Basket clearBasketDataById(String id) {
22+
Query query = new Query().addCriteria(where("_id").is(id));
23+
24+
Update update = new Update();
25+
update.set("data", new BasketData());
26+
27+
return mongoTemplate.findAndModify(query, update, Basket.class);
28+
}
29+
}

src/main/java/uk/gov/companieshouse/orders/api/service/BasketService.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,8 @@ public Basket saveBasket(Basket basket) {
3131
public Optional<Basket> getBasketById(String id) {
3232
return repository.findById(id);
3333
}
34+
35+
public Basket clearBasket(String id) {
36+
return repository.clearBasketDataById(id);
37+
}
3438
}

src/test/java/uk/gov/companieshouse/orders/api/controller/BasketControllerIntegrationTest.java

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import uk.gov.companieshouse.orders.api.model.Certificate;
2020
import uk.gov.companieshouse.orders.api.model.Checkout;
2121
import uk.gov.companieshouse.orders.api.model.Item;
22+
import uk.gov.companieshouse.orders.api.model.PaymentStatus;
2223
import uk.gov.companieshouse.orders.api.repository.BasketRepository;
2324
import uk.gov.companieshouse.orders.api.repository.CheckoutRepository;
2425
import uk.gov.companieshouse.orders.api.service.ApiClientService;
@@ -244,7 +245,7 @@ public void patchBasketPaymentDetailsReturnsOK() throws Exception {
244245
BasketPaymentRequestDTO basketPaymentRequestDTO = new BasketPaymentRequestDTO();
245246
basketPaymentRequestDTO.setPaidAt("paid-at");
246247
basketPaymentRequestDTO.setPaymentReference("reference");
247-
basketPaymentRequestDTO.setStatus("status");
248+
basketPaymentRequestDTO.setStatus(PaymentStatus.PAID);
248249

249250
mockMvc.perform(patch("/basket/payment/1234")
250251
.header(REQUEST_ID_HEADER_NAME, TOKEN_REQUEST_ID_VALUE)
@@ -253,4 +254,56 @@ public void patchBasketPaymentDetailsReturnsOK() throws Exception {
253254
.content(mapper.writeValueAsString(basketPaymentRequestDTO)))
254255
.andExpect(status().isOk());
255256
}
257+
258+
@Test
259+
@DisplayName("Patch basket payment details clears basket is status is paid")
260+
public void patchBasketPaymentDetailsClearsBasketStatusPaid() throws Exception {
261+
Basket basket = new Basket();
262+
basket.setId(ERIC_IDENTITY_VALUE);
263+
BasketItem basketItem = new BasketItem();
264+
basketItem.setItemUri(ITEM_URI);
265+
basket.getData().getItems().add(basketItem);
266+
basketRepository.save(basket);
267+
268+
BasketPaymentRequestDTO basketPaymentRequestDTO = new BasketPaymentRequestDTO();
269+
basketPaymentRequestDTO.setPaidAt("paid-at");
270+
basketPaymentRequestDTO.setPaymentReference("reference");
271+
basketPaymentRequestDTO.setStatus(PaymentStatus.PAID);
272+
273+
mockMvc.perform(patch("/basket/payment/1234")
274+
.header(REQUEST_ID_HEADER_NAME, TOKEN_REQUEST_ID_VALUE)
275+
.header(ERIC_IDENTITY_HEADER_NAME, ERIC_IDENTITY_VALUE)
276+
.contentType(MediaType.APPLICATION_JSON)
277+
.content(mapper.writeValueAsString(basketPaymentRequestDTO)))
278+
.andExpect(status().isOk());
279+
280+
final Optional<Basket> retrievedBasket = basketRepository.findById(ERIC_IDENTITY_VALUE);
281+
assertTrue(retrievedBasket.get().getData().getItems().isEmpty());
282+
}
283+
284+
@Test
285+
@DisplayName("Patch basket payment details does not clear basket is status is not paid")
286+
public void patchBasketPaymentDetailsDoesNotClearBasketStatusNotPaid() throws Exception {
287+
Basket basket = new Basket();
288+
basket.setId(ERIC_IDENTITY_VALUE);
289+
BasketItem basketItem = new BasketItem();
290+
basketItem.setItemUri(ITEM_URI);
291+
basket.getData().getItems().add(basketItem);
292+
basketRepository.save(basket);
293+
294+
BasketPaymentRequestDTO basketPaymentRequestDTO = new BasketPaymentRequestDTO();
295+
basketPaymentRequestDTO.setPaidAt("paid-at");
296+
basketPaymentRequestDTO.setPaymentReference("reference");
297+
basketPaymentRequestDTO.setStatus(PaymentStatus.FAILED);
298+
299+
mockMvc.perform(patch("/basket/payment/1234")
300+
.header(REQUEST_ID_HEADER_NAME, TOKEN_REQUEST_ID_VALUE)
301+
.header(ERIC_IDENTITY_HEADER_NAME, ERIC_IDENTITY_VALUE)
302+
.contentType(MediaType.APPLICATION_JSON)
303+
.content(mapper.writeValueAsString(basketPaymentRequestDTO)))
304+
.andExpect(status().isOk());
305+
306+
final Optional<Basket> retrievedBasket = basketRepository.findById(ERIC_IDENTITY_VALUE);
307+
assertFalse(retrievedBasket.get().getData().getItems().isEmpty());
308+
}
256309
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package uk.gov.companieshouse.orders.api.repository;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.junit.jupiter.api.extension.ExtendWith;
5+
import org.mockito.InjectMocks;
6+
import org.mockito.Mock;
7+
import org.mockito.junit.jupiter.MockitoExtension;
8+
import org.springframework.data.mongodb.core.MongoTemplate;
9+
import org.springframework.data.mongodb.core.query.Query;
10+
import org.springframework.data.mongodb.core.query.Update;
11+
import uk.gov.companieshouse.orders.api.model.Basket;
12+
13+
import static org.mockito.ArgumentMatchers.any;
14+
import static org.mockito.ArgumentMatchers.eq;
15+
import static org.mockito.Mockito.times;
16+
import static org.mockito.Mockito.verify;
17+
18+
@ExtendWith(MockitoExtension.class)
19+
public class BasketRespositoryImplTest {
20+
21+
@InjectMocks
22+
private BasketRepositoryImpl repositoryUnderTest;
23+
24+
@Mock
25+
MongoTemplate mongoTemplate;
26+
27+
@Test
28+
public void clearBasketDataByIdVerifyFindAndModifyCalledOnce() {
29+
repositoryUnderTest.clearBasketDataById("ID");
30+
verify(mongoTemplate, times(1)).findAndModify(any(Query.class), any(Update.class), eq(Basket.class));
31+
}
32+
33+
}

0 commit comments

Comments
 (0)