Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#48 When querying getItem or getItems with a strongly typed class, automatically add a query filter for system type #55

Merged
merged 2 commits into from
Feb 6, 2018
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
20 changes: 16 additions & 4 deletions src/main/java/com/kenticocloud/delivery/DeliveryClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,13 @@
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.UUID;
import java.util.*;

/**
* Executes requests against the Kentico Cloud Delivery API.
Expand Down Expand Up @@ -198,6 +196,7 @@ public ContentItemsListingResponse getItems(List<NameValuePair> params) throws I
}

public <T> List<T> getItems(Class<T> tClass, List<NameValuePair> params) throws IOException {
addTypeParameterIfNecessary(tClass, params);
ContentItemsListingResponse contentItemsListingResponse = getItems(params);
return contentItemsListingResponse.castTo(tClass);
}
Expand Down Expand Up @@ -255,6 +254,7 @@ public ContentItemResponse getItem(String contentItemCodename, List<NameValuePai
}

public <T> T getItem(String contentItemCodename, Class<T> tClass, List<NameValuePair> params) throws IOException {
addTypeParameterIfNecessary(tClass, params);
ContentItemResponse contentItemResponse = getItem(contentItemCodename, params);
return contentItemResponse.castTo(tClass);
}
Expand Down Expand Up @@ -435,6 +435,18 @@ private void handleErrorIfNecessary(HttpResponse response) throws IOException {
}
}

private void addTypeParameterIfNecessary(Class tClass, List<NameValuePair> params) {
Optional<NameValuePair> any = params.stream()
.filter(nameValuePair -> nameValuePair.getName().equals("system.type"))
.findAny();
if (!any.isPresent()) {
String contentType = stronglyTypedContentItemConverter.getContentType(tClass);
if (contentType != null) {
params.add(new BasicNameValuePair("system.type", contentType));
}
}
}

private void reconfigureDeserializer() {
objectMapper = new ObjectMapper();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ protected void registerType(Class<?> clazz) {
logger.debug("Registered type for {}", clazz.getSimpleName());
}

protected String getContentType(Class tClass) {
if (classToContentTypeMapping.containsKey(tClass)) {
return classToContentTypeMapping.get(tClass);
}
return null;
}

protected void registerInlineContentItemsResolver(InlineContentItemsResolver resolver) {
typeToInlineResolverMapping.put(resolver.getType(), resolver);
}
Expand Down
124 changes: 114 additions & 10 deletions src/test/java/com/kenticocloud/delivery/DeliveryClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -484,11 +484,20 @@ public void testGetStronglyTypedItemByRegisteringType() throws Exception {

this.serverBootstrap.registerHandler(
String.format("/%s/%s", projectId, "items/on_roasts"),
(request, response, context) -> response.setEntity(
new InputStreamEntity(
this.getClass().getResourceAsStream("SampleContentItem.json")
)
));
(request, response, context) -> {
String uri = String.format("http://testserver%s", request.getRequestLine().getUri());

List<NameValuePair> nameValuePairs =
URLEncodedUtils.parse(URI.create(uri), Charset.defaultCharset());
Assert.assertFalse(nameValuePairs.stream()
.anyMatch(nameValuePair -> nameValuePair.getName().equals("system.type")));

response.setEntity(
new InputStreamEntity(
this.getClass().getResourceAsStream("SampleContentItem.json")
)
);
});
HttpHost httpHost = this.start();
DeliveryClient client = new DeliveryClient(projectId);
client.registerType("article", ArticleItem.class);
Expand All @@ -504,6 +513,90 @@ public void testGetStronglyTypedItemByRegisteringType() throws Exception {
Assert.assertTrue(itemObj instanceof ArticleItem);
}

@Test
public void testGetStronglyTypedItemAutomaticallyAddsSystemType() throws Exception {
String projectId = "02a70003-e864-464e-b62c-e0ede97deb8c";

this.serverBootstrap.registerHandler(
String.format("/%s/%s", projectId, "items/on_roasts"),
(request, response, context) -> {
String uri = String.format("http://testserver%s", request.getRequestLine().getUri());

List<NameValuePair> nameValuePairs =
URLEncodedUtils.parse(URI.create(uri), Charset.defaultCharset());
Assert.assertEquals(1, nameValuePairs.stream()
.filter(nameValuePair -> nameValuePair.getName().equals("system.type"))
.count());

Map<String, String> params = convertNameValuePairsToMap(nameValuePairs);

Assert.assertTrue(params.containsKey("system.type"));
Assert.assertEquals("article", params.get("system.type"));

response.setEntity(
new InputStreamEntity(
this.getClass().getResourceAsStream("SampleContentItem.json")
)
);
});
HttpHost httpHost = this.start();
DeliveryClient client = new DeliveryClient(projectId);
client.registerType("article", ArticleItem.class);

//modify default baseurl to point to test server, this is private so using reflection
String testServerUri = httpHost.toURI() + "/%s";
Field deliveryOptionsField = client.getClass().getDeclaredField("deliveryOptions");
deliveryOptionsField.setAccessible(true);
((DeliveryOptions) deliveryOptionsField.get(client)).setProductionEndpoint(testServerUri);

ArticleItem itemObj = client.getItem("on_roasts", ArticleItem.class);
Assert.assertNotNull(itemObj);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the tests are not conclusive. they'd pass even if the new type detection logic was not present because you're filtering by codename in the first place.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ultimately, the test hits a mocked server, which limits it's usefulness for the edge you are bringing up, but the mock server is checking for the parameter to be present. I would expect that in a real world scenario, if you filtered by system.type=article, and codename=some_non_article, that the API wouldn't respond with any results, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test hits the view a content item API, which requires a code name: https://developer.kenticocloud.com/v1/reference#view-a-content-item

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct. 👍 i didn't notice the check on the mocked server. merging

}

@Test
public void testGetStronglyTypedItemAutomaticallyDoesNotSentSystemTypeWhenAdded() throws Exception {
String projectId = "02a70003-e864-464e-b62c-e0ede97deb8c";

this.serverBootstrap.registerHandler(
String.format("/%s/%s", projectId, "items/on_roasts"),
(request, response, context) -> {
String uri = String.format("http://testserver%s", request.getRequestLine().getUri());

List<NameValuePair> nameValuePairs =
URLEncodedUtils.parse(URI.create(uri), Charset.defaultCharset());
Assert.assertEquals(1, nameValuePairs.stream()
.filter(nameValuePair -> nameValuePair.getName().equals("system.type"))
.count());
Map<String, String> params = convertNameValuePairsToMap(nameValuePairs);

Assert.assertTrue(params.containsKey("system.type"));
Assert.assertEquals("customVal", params.get("system.type"));

response.setEntity(
new InputStreamEntity(
this.getClass().getResourceAsStream("SampleContentItem.json")
)
);
});
HttpHost httpHost = this.start();
DeliveryClient client = new DeliveryClient(projectId);
client.registerType("article", ArticleItem.class);

//modify default baseurl to point to test server, this is private so using reflection
String testServerUri = httpHost.toURI() + "/%s";
Field deliveryOptionsField = client.getClass().getDeclaredField("deliveryOptions");
deliveryOptionsField.setAccessible(true);
((DeliveryOptions) deliveryOptionsField.get(client)).setProductionEndpoint(testServerUri);

ArticleItem itemObj = client.getItem(
"on_roasts",
ArticleItem.class,
DeliveryParameterBuilder.params()
.filterEquals("system.type", "customVal")
.build());
Assert.assertNotNull(itemObj);
}

@Test
public void testGetStronglyTypedItemByRegisteringMapping() throws Exception {
String projectId = "02a70003-e864-464e-b62c-e0ede97deb8c";
Expand Down Expand Up @@ -654,11 +747,22 @@ public void testGetStronglyTypedItems() throws Exception {

this.serverBootstrap.registerHandler(
String.format("/%s/%s", projectId, "items"),
(request, response, context) -> response.setEntity(
new InputStreamEntity(
this.getClass().getResourceAsStream("SampleContentItemList.json")
)
));
(request, response, context) -> {
String uri = String.format("http://testserver%s", request.getRequestLine().getUri());

List<NameValuePair> nameValuePairs =
URLEncodedUtils.parse(URI.create(uri), Charset.defaultCharset());
Map<String, String> params = convertNameValuePairsToMap(nameValuePairs);

Assert.assertTrue(params.containsKey("system.type"));
Assert.assertEquals("article", params.get("system.type"));

response.setEntity(
new InputStreamEntity(
this.getClass().getResourceAsStream("SampleContentItemList.json")
)
);
});
HttpHost httpHost = this.start();
DeliveryClient client = new DeliveryClient(projectId);

Expand Down