Skip to content

Commit daa9b67

Browse files
authored
Merge pull request #137 from companieshouse/feature/gci-2203_toggle_product_class_cnum
GCI-2203 Toggle checkout search fields
2 parents d5cbd1f + 27780a8 commit daa9b67

15 files changed

+384
-18
lines changed

src/main/java/uk/gov/companieshouse/orders/api/config/FeatureOptions.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@
33
public class FeatureOptions {
44

55
private final boolean ordersSearchEndpointEnabled;
6+
private final boolean multiItemBasketSearchEnabled;
67

7-
public FeatureOptions(boolean ordersSearchEndpointEnabled) {
8+
public FeatureOptions(boolean ordersSearchEndpointEnabled, boolean multiItemBasketSearchEnabled) {
89
this.ordersSearchEndpointEnabled = ordersSearchEndpointEnabled;
10+
this.multiItemBasketSearchEnabled = multiItemBasketSearchEnabled;
911
}
1012

1113
public boolean isOrdersSearchEndpointEnabled() {
1214
return ordersSearchEndpointEnabled;
1315
}
16+
17+
public boolean isMultiItemBasketSearchEnabled() {
18+
return multiItemBasketSearchEnabled;
19+
}
1420
}

src/main/java/uk/gov/companieshouse/orders/api/config/FeatureOptionsConfig.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@ public class FeatureOptionsConfig {
1010
@Value("${feature.options.ordersSearchEndpointEnabled:false}")
1111
private boolean ordersSearchEnabled;
1212

13+
@Value("${feature.options.multiItemBasketSearchEnabled:false}")
14+
private boolean multiItemBasketSearchEnabled;
15+
1316
@Bean
1417
public FeatureOptions featureOptions() {
15-
return new FeatureOptions(ordersSearchEnabled);
18+
return new FeatureOptions(ordersSearchEnabled, multiItemBasketSearchEnabled);
1619
}
1720
}

src/main/java/uk/gov/companieshouse/orders/api/exception/ServiceException.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@ public ServiceException(String message) {
66
super(message);
77
}
88

9+
public ServiceException(String message, Throwable cause) {
10+
super(message, cause);
11+
}
912
}

src/main/java/uk/gov/companieshouse/orders/api/model/CheckoutSummary.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public static Builder newBuilder() {
2626
return new Builder();
2727
}
2828

29-
public static final class Builder {
29+
public static final class Builder implements CheckoutSummaryBuildable {
3030
private String id;
3131
private String email;
3232
private String companyNumber;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package uk.gov.companieshouse.orders.api.model;
2+
3+
import java.time.LocalDateTime;
4+
5+
public interface CheckoutSummaryBuildable {
6+
CheckoutSummaryBuildable withId(String id);
7+
CheckoutSummaryBuildable withEmail(String email);
8+
CheckoutSummaryBuildable withCompanyNumber(String companyNumber);
9+
CheckoutSummaryBuildable withProductLine(String productLine);
10+
CheckoutSummaryBuildable withCheckoutDate(LocalDateTime checkoutDate);
11+
CheckoutSummaryBuildable withPaymentStatus(PaymentStatus paymentStatus);
12+
CheckoutSummaryBuildable withLinks(Links links);
13+
CheckoutSummary build();
14+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package uk.gov.companieshouse.orders.api.model;
2+
3+
import java.lang.reflect.Proxy;
4+
import org.springframework.stereotype.Component;
5+
import uk.gov.companieshouse.orders.api.config.FeatureOptions;
6+
7+
@Component
8+
public class CheckoutSummaryBuilderFactory {
9+
10+
private final FeatureOptions featureOptions;
11+
12+
public CheckoutSummaryBuilderFactory(FeatureOptions featureOptions) {
13+
this.featureOptions = featureOptions;
14+
}
15+
16+
public CheckoutSummaryBuildable newCheckoutSummaryBuilder() {
17+
CheckoutSummaryBuildable builder = CheckoutSummary.newBuilder();
18+
return (CheckoutSummaryBuildable) Proxy.newProxyInstance(
19+
builder.getClass().getClassLoader(),
20+
builder.getClass().getInterfaces(),
21+
new CheckoutSummaryInvocationHandler(this.featureOptions, builder));
22+
}
23+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package uk.gov.companieshouse.orders.api.model;
2+
3+
import java.lang.reflect.InvocationHandler;
4+
import java.lang.reflect.InvocationTargetException;
5+
import java.lang.reflect.Method;
6+
import uk.gov.companieshouse.orders.api.config.FeatureOptions;
7+
import uk.gov.companieshouse.orders.api.exception.ServiceException;
8+
9+
public class CheckoutSummaryInvocationHandler implements InvocationHandler {
10+
11+
private final CheckoutSummaryBuildable builder;
12+
private final FeatureOptions featureOptions;
13+
14+
public CheckoutSummaryInvocationHandler(FeatureOptions featureOptions, CheckoutSummaryBuildable builder) {
15+
this.builder = builder;
16+
this.featureOptions = featureOptions;
17+
}
18+
19+
@Override
20+
public Object invoke(Object proxy, Method method, Object[] args) {
21+
try {
22+
if ("withCompanyNumber".equals(method.getName())
23+
&& featureOptions.isMultiItemBasketSearchEnabled()) {
24+
return proxy;
25+
} else if ("withProductLine".equals(method.getName())
26+
&& featureOptions.isMultiItemBasketSearchEnabled()) {
27+
return proxy;
28+
} else if (method.getName().startsWith("with")) {
29+
method.invoke(builder, args);
30+
return proxy;
31+
} else {
32+
return method.invoke(builder, args);
33+
}
34+
} catch (InvocationTargetException | IllegalAccessException e) {
35+
throw new ServiceException("Error mapping checkout summary", e);
36+
}
37+
}
38+
}

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,20 @@ public class CheckoutService {
2323
private final LinksGeneratorService linksGeneratorService;
2424
private final CheckoutHelper checkoutHelper;
2525
private final SearchFieldMapper searchFieldMapper;
26+
private final CheckoutSummaryBuilderFactory summaryBuilderFactory;
2627

2728
public CheckoutService(CheckoutRepository checkoutRepository,
2829
EtagGeneratorService etagGeneratorService,
2930
LinksGeneratorService linksGeneratorService,
3031
CheckoutHelper checkoutHelper,
31-
SearchFieldMapper searchFieldMapper) {
32+
SearchFieldMapper searchFieldMapper,
33+
CheckoutSummaryBuilderFactory summaryBuilderFactory) {
3234
this.checkoutRepository = checkoutRepository;
3335
this.etagGeneratorService = etagGeneratorService;
3436
this.linksGeneratorService = linksGeneratorService;
3537
this.checkoutHelper = checkoutHelper;
3638
this.searchFieldMapper = searchFieldMapper;
39+
this.summaryBuilderFactory = summaryBuilderFactory;
3740
}
3841

3942
private String autoGenerateId() {
@@ -97,7 +100,7 @@ public CheckoutSearchResults searchCheckouts(CheckoutSearchCriteria checkoutSear
97100

98101
return new CheckoutSearchResults(checkoutPages.getTotalElements(),
99102
checkouts.stream().map(
100-
checkout -> CheckoutSummary.newBuilder()
103+
checkout -> summaryBuilderFactory.newCheckoutSummaryBuilder()
101104
.withId(checkout.getId())
102105
.withEmail(
103106
Optional.ofNullable(checkout.getData())

src/main/resources/application.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ spring.data.mongodb.field-naming-strategy=uk.gov.companieshouse.orders.api.model
1414

1515
spring.kafka.producer.bootstrap-servers: ${KAFKA_BROKER_ADDR}
1616

17-
feature.options.ordersSearchEndpointEnabled=${ORDERS_SEARCH_ENDPOINT_ENABLED:false}
17+
feature.options.ordersSearchEndpointEnabled=${ORDERS_SEARCH_ENDPOINT_ENABLED:false}
18+
feature.options.multiItemBasketSearchEnabled=${ORDERS_SEARCH_MULTIBASKET_ENABLED:false}

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

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
@AutoConfigureMockMvc
7878
@SpringBootTest
7979
@EmbeddedKafka
80-
@ActiveProfiles("orders-search-enabled")
80+
@ActiveProfiles({"orders-search-enabled", "orders-search-multibasket-enabled"})
8181
class OrderControllerIntegrationTest {
8282
private static final String ORDER_ID = "0001";
8383
private static final String ORDER_REFERENCE = "0001";
@@ -252,8 +252,6 @@ void searchCheckoutsById() throws Exception {
252252
CheckoutSummary.newBuilder()
253253
.withId(CHECKOUT_ID)
254254
.withEmail("[email protected]")
255-
.withCompanyNumber("12345678")
256-
.withProductLine("item#certificate")
257255
.withPaymentStatus(PaymentStatus.PAID)
258256
.withCheckoutDate(LocalDate.of(2022, 4, 12).atStartOfDay())
259257
.withLinks(new Links(new HRef("http"), new HRef("http")))
@@ -269,7 +267,7 @@ void searchCheckoutsById() throws Exception {
269267
.header(ERIC_AUTHORISED_TOKEN_PERMISSIONS, String.format(TOKEN_PERMISSION_VALUE, Permission.Value.READ))
270268
.contentType(MediaType.APPLICATION_JSON))
271269
.andExpect(status().isOk())
272-
.andExpect(content().json(mapper.writeValueAsString(expected)));
270+
.andExpect(content().json(mapper.writeValueAsString(expected), true));
273271
}
274272

275273
@DisplayName("Should find a single checkout when searching with a partial email address")
@@ -281,8 +279,6 @@ void searchCheckoutsByEmail() throws Exception {
281279
CheckoutSummary.newBuilder()
282280
.withId(CHECKOUT_ID)
283281
.withEmail("[email protected]")
284-
.withCompanyNumber("12345678")
285-
.withProductLine("item#certificate")
286282
.withPaymentStatus(PaymentStatus.PAID)
287283
.withCheckoutDate(LocalDate.of(2022, 4, 12).atStartOfDay())
288284
.withLinks(new Links(new HRef("http"), new HRef("http")))
@@ -298,7 +294,7 @@ void searchCheckoutsByEmail() throws Exception {
298294
.header(ERIC_AUTHORISED_TOKEN_PERMISSIONS, String.format(TOKEN_PERMISSION_VALUE, Permission.Value.READ))
299295
.contentType(MediaType.APPLICATION_JSON))
300296
.andExpect(status().isOk())
301-
.andExpect(content().json(mapper.writeValueAsString(expected)));
297+
.andExpect(content().json(mapper.writeValueAsString(expected), true));
302298
}
303299

304300
@DisplayName("Should find a single checkout when a valid company number is provided")
@@ -312,8 +308,6 @@ void searchCheckoutsByCompanyNumber() throws Exception {
312308
CheckoutSummary.newBuilder()
313309
.withId(ORDER_ID)
314310
.withEmail("[email protected]")
315-
.withCompanyNumber("12345678")
316-
.withProductLine("item#certificate")
317311
.withPaymentStatus(PaymentStatus.PAID)
318312
.withCheckoutDate(LocalDate.of(2022, 4, 12).atStartOfDay())
319313
.withLinks(new Links(new HRef("http"), new HRef("http")))
@@ -329,7 +323,7 @@ void searchCheckoutsByCompanyNumber() throws Exception {
329323
.header(ERIC_AUTHORISED_TOKEN_PERMISSIONS, String.format(TOKEN_PERMISSION_VALUE, Permission.Value.READ))
330324
.contentType(MediaType.APPLICATION_JSON))
331325
.andExpect(status().isOk())
332-
.andExpect(content().json(mapper.writeValueAsString(expected)));
326+
.andExpect(content().json(mapper.writeValueAsString(expected), true));
333327
}
334328

335329
@ParameterizedTest(name = "{index}: {0}")
@@ -348,7 +342,7 @@ void searchReturnsNoMatches(final String displayName, final String searchField,
348342
.header(ERIC_AUTHORISED_TOKEN_PERMISSIONS, String.format(TOKEN_PERMISSION_VALUE, Permission.Value.READ))
349343
.contentType(MediaType.APPLICATION_JSON))
350344
.andExpect(status().isOk())
351-
.andExpect(content().json(mapper.writeValueAsString(expected)));
345+
.andExpect(content().json(mapper.writeValueAsString(expected), true));
352346
}
353347

354348
@DisplayName("Should return a page containing a single order when page_size is one")
@@ -578,7 +572,7 @@ private MockHttpServletRequestBuilder reprocessOrderWithRequiredCredentials() {
578572
.contentType(MediaType.APPLICATION_JSON);
579573
}
580574

581-
private static Stream<Arguments> noMatchesFixture() {
575+
static Stream<Arguments> noMatchesFixture() {
582576
return Stream.of(Arguments.arguments("Should not find a order when incomplete order id is provided", "id", "00"),
583577
Arguments.arguments("Should not find a order when a incorrect email address is provided", "email", "[email protected]"),
584578
Arguments.arguments("Should not find a order when a incomplete company number is provided", "company_number", "345678912"));

0 commit comments

Comments
 (0)