From 977873b4f64e91451e176e9194daea41b6569fa2 Mon Sep 17 00:00:00 2001 From: Piotr Brandt Date: Wed, 25 Jan 2017 11:40:03 +0100 Subject: [PATCH 1/9] refactor contentful cms page implementation to improve readability --- .../cms/contentful/ContentfulCmsPage.java | 115 ++++++++++-------- 1 file changed, 63 insertions(+), 52 deletions(-) diff --git a/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java b/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java index 55a2282..25715d3 100644 --- a/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java +++ b/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java @@ -7,9 +7,9 @@ import com.contentful.java.cda.CDAField; import org.apache.commons.lang3.StringUtils; -import javax.annotation.Nullable; import java.util.*; +import static java.util.Arrays.copyOfRange; import static org.apache.commons.lang3.StringUtils.split; public class ContentfulCmsPage implements CmsPage { @@ -17,76 +17,87 @@ public class ContentfulCmsPage implements CmsPage { private CDAEntry cdaEntry; private List locales; - public ContentfulCmsPage(CDAEntry cdaEntry, List locales) { + public ContentfulCmsPage(final CDAEntry cdaEntry, final List locales) { this.cdaEntry = cdaEntry; this.locales = locales; } @Override - public Optional field(final String fieldName) { - if (StringUtils.isEmpty(fieldName)) { + public Optional field(final String path) { + if (StringUtils.isEmpty(path)) { return Optional.empty(); } - final List allNames = new ArrayList<>(Arrays.asList(split(fieldName, "."))); - return Optional.ofNullable(getEntryWithContentField(cdaEntry, getEntryNamesList(allNames))) - .flatMap(entryWithContentField -> - getContent(entryWithContentField, getContentFieldName(allNames))); - } - - private String getContentFieldName(List allNames) { - return allNames.size() > 1 ? allNames.get(allNames.size() - 1) : allNames.get(0); - } - private List getEntryNamesList(List allNames) { - return allNames.size() > 1 ? - allNames.subList(0, allNames.size() - 1) : Collections.emptyList(); + final String[] pathSegments = split(path, "."); + final String fieldKey = pathSegments[pathSegments.length - 1]; + final String[] entryPathSegments = createEntryPathSegments(pathSegments); + return findEntry(entryPathSegments).flatMap(lastEntry -> + findContent(lastEntry, fieldKey)); } - private Optional getContent(final CDAEntry entry, final String contentFieldName) { - return getCdaField(entry, contentFieldName) - .flatMap(cdaField -> { - final Object entryField = entry.getField(contentFieldName); - return getContentAccordingToFieldDefinition(entryField, cdaField); - }); + /** + * Skip last segment which is expected to be a field name. + * + * @param pathSegments entire path segments + * @return path segments of entries only + */ + private String[] createEntryPathSegments(final String[] pathSegments) { + return copyOfRange(pathSegments, 0, pathSegments.length - 1); } - private CDAEntry getEntryWithContentField(@Nullable final CDAEntry cdaEntry, final List entryNamesList) { - if (entryNamesList.isEmpty()) { - return cdaEntry; - } else { - final String key = entryNamesList.get(0); - if (cdaEntry != null && cdaEntry.rawFields().containsKey(key)) { - Object item = cdaEntry.getField(key); - if (item instanceof CDAEntry) { - entryNamesList.remove(0); - return getEntryWithContentField((CDAEntry) item, entryNamesList); + /** + * Traverse contained CDAEntry to match all path segments. + * + * @param pathSegments array of all path segments that lead to CDAEntry of interest + * @return CDAEntry that matches path segments + */ + private Optional findEntry(final String[] pathSegments) { + CDAEntry entry = cdaEntry; + for (String key: pathSegments) { + if (entry.rawFields().containsKey(key)) { + Object field = entry.getField(key); + if (field instanceof CDAEntry) { + entry = (CDAEntry) field; + } else { + return Optional.empty(); } + } else { + return Optional.empty(); } - return null; } + return Optional.of(entry); + } + + private Optional findContent(final CDAEntry entry, final String fieldKey) { + return getField(entry, fieldKey).flatMap(field -> + findContentTypeField(entry, fieldKey).flatMap(contentTypeField -> + getContentBasedOnType(field, contentTypeField))); + } + + private Optional getField(final CDAEntry entry, final String fieldKey) { + return Optional.ofNullable(entry.getField(fieldKey)); } - // CDAField contains information related to field, like it's type - private Optional getCdaField(final CDAEntry lastLevelEntry, final String fieldName) { - return lastLevelEntry.contentType().fields() - .stream() - .filter(cdaField -> cdaField.id().equals(fieldName) - && FieldTypes.ALL_SUPPORTED.contains(cdaField.type())) - .findFirst(); + private Optional findContentTypeField(final CDAEntry entry, final String fieldKey) { + return entry.contentType().fields().stream() + .filter(field -> field.id().equals(fieldKey) && FieldTypes.ALL_SUPPORTED.contains(field.type())) + .findAny(); } - private Optional getContentAccordingToFieldDefinition(@Nullable final Object localizedEntryField, - final CDAField cdaField) { - return Optional.ofNullable(localizedEntryField) - .map(entryField -> { - String content = null; - if (FieldTypes.CONVERTABLE_TO_STRING.contains(cdaField.type())) { - content = String.valueOf(entryField); - } else if (cdaField.linkType().equals(FieldTypes.LINK_ASSET)) { - content = ((CDAAsset) entryField).url(); - } - return content; - }); + /** + * Convert content of the field to String if possible. + * + * @param entryField object to convert to string + * @param contentTypeField information about object's type + * @return content of the field in String representation if possible + */ + private Optional getContentBasedOnType(final Object entryField, final CDAField contentTypeField) { + if (FieldTypes.CONVERTABLE_TO_STRING.contains(contentTypeField.type())) { + return Optional.of(String.valueOf(entryField)); + } else if (FieldTypes.LINK_ASSET.equals(contentTypeField.linkType())) { + return Optional.ofNullable(((CDAAsset) entryField).url()); + } + return Optional.empty(); } } From ea5b621240a0632319f614f91a5b6efa6f8fa83a Mon Sep 17 00:00:00 2001 From: Piotr Brandt Date: Wed, 25 Jan 2017 14:30:32 +0100 Subject: [PATCH 2/9] extend contentful cms page implementation to support querying array entries --- .../cms/contentful/ContentfulCmsPage.java | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java b/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java index 25715d3..ba99a46 100644 --- a/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java +++ b/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java @@ -8,12 +8,16 @@ import org.apache.commons.lang3.StringUtils; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static java.util.Arrays.copyOfRange; import static org.apache.commons.lang3.StringUtils.split; public class ContentfulCmsPage implements CmsPage { + private static final Pattern ARRAY_KEY_PATTERN = Pattern.compile("(.+)\\[(\\d+)\\]$"); + private CDAEntry cdaEntry; private List locales; @@ -53,21 +57,43 @@ private String[] createEntryPathSegments(final String[] pathSegments) { */ private Optional findEntry(final String[] pathSegments) { CDAEntry entry = cdaEntry; + for (String key: pathSegments) { - if (entry.rawFields().containsKey(key)) { - Object field = entry.getField(key); - if (field instanceof CDAEntry) { - entry = (CDAEntry) field; - } else { - return Optional.empty(); - } + Object nextEntry = null; + + Matcher arrayMatcher = ARRAY_KEY_PATTERN.matcher(key); + + if (arrayMatcher.find()) { + String arrayKey = arrayMatcher.group(1); + int index = Integer.parseInt(arrayMatcher.group(2)); + nextEntry = getEntryFromArray(entry, arrayKey, index); + } else if (entry.rawFields().containsKey(key)) { + nextEntry = entry.getField(key); + } + + if (nextEntry != null && nextEntry instanceof CDAEntry) { + entry = (CDAEntry) nextEntry; } else { return Optional.empty(); } } + return Optional.of(entry); } + private Object getEntryFromArray(CDAEntry parentEntry, String arrayFieldKey, int index) { + if (parentEntry.rawFields().containsKey(arrayFieldKey)) { + Object field = parentEntry.getField(arrayFieldKey); + if (field instanceof ArrayList) { + ArrayList arrayList = (ArrayList) field; + if (index < arrayList.size()) { + return arrayList.get(index); + } + } + } + return null; + } + private Optional findContent(final CDAEntry entry, final String fieldKey) { return getField(entry, fieldKey).flatMap(field -> findContentTypeField(entry, fieldKey).flatMap(contentTypeField -> From b9a57c754b24076f57136e45318650369ee6bda5 Mon Sep 17 00:00:00 2001 From: Piotr Brandt Date: Thu, 26 Jan 2017 15:01:09 +0100 Subject: [PATCH 3/9] extend contentful cms page implementation to support field arrays and Location type --- .../cms/contentful/ContentfulCmsPage.java | 102 ++++++++++++++---- .../cms/contentful/models/FieldType.java | 75 +++++++++++++ .../cms/contentful/models/FieldTypes.java | 27 ----- 3 files changed, 159 insertions(+), 45 deletions(-) create mode 100644 cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/models/FieldType.java delete mode 100644 cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/models/FieldTypes.java diff --git a/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java b/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java index ba99a46..da37cbc 100644 --- a/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java +++ b/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java @@ -1,7 +1,6 @@ package com.commercetools.sunrise.cms.contentful; import com.commercetools.sunrise.cms.CmsPage; -import com.commercetools.sunrise.cms.contentful.models.FieldTypes; import com.contentful.java.cda.CDAAsset; import com.contentful.java.cda.CDAEntry; import com.contentful.java.cda.CDAField; @@ -11,6 +10,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import static com.commercetools.sunrise.cms.contentful.models.FieldType.hasStringRepresentation; +import static com.commercetools.sunrise.cms.contentful.models.FieldType.isAsset; +import static com.commercetools.sunrise.cms.contentful.models.FieldType.isSupported; import static java.util.Arrays.copyOfRange; import static org.apache.commons.lang3.StringUtils.split; @@ -40,7 +42,7 @@ public Optional field(final String path) { } /** - * Skip last segment which is expected to be a field name. + * Form an array with last segment skipped which is expected to be a field name. * * @param pathSegments entire path segments * @return path segments of entries only @@ -64,9 +66,7 @@ private Optional findEntry(final String[] pathSegments) { Matcher arrayMatcher = ARRAY_KEY_PATTERN.matcher(key); if (arrayMatcher.find()) { - String arrayKey = arrayMatcher.group(1); - int index = Integer.parseInt(arrayMatcher.group(2)); - nextEntry = getEntryFromArray(entry, arrayKey, index); + nextEntry = getEntryFromArray(entry, arrayMatcher); } else if (entry.rawFields().containsKey(key)) { nextEntry = entry.getField(key); } @@ -81,9 +81,26 @@ private Optional findEntry(final String[] pathSegments) { return Optional.of(entry); } - private Object getEntryFromArray(CDAEntry parentEntry, String arrayFieldKey, int index) { - if (parentEntry.rawFields().containsKey(arrayFieldKey)) { - Object field = parentEntry.getField(arrayFieldKey); + /** + * Try to get an item from input entry which is supposed to contain an array of fields. + * + * After pattern has been matched arrayMatcher contains a regexp group of key and index. + * E.g. after matching 'key[1]' two groups of 'key' and '1' are contained in matcher. + * + * They are later used to find 'key' field in parentEntry and retrieve '1' (second) + * item from that field which is expected to form an array list. + * + * If the process fails null is returned. + * + * @param parentEntry should contain expected array field + * @param arrayMatcher contains key and index groups after pattern has been matched + * @return matched entry or null + */ + private Object getEntryFromArray(final CDAEntry parentEntry, final Matcher arrayMatcher) { + String arrayEntryKey = arrayMatcher.group(1); + int index = Integer.parseInt(arrayMatcher.group(2)); + if (parentEntry.rawFields().containsKey(arrayEntryKey)) { + Object field = parentEntry.getField(arrayEntryKey); if (field instanceof ArrayList) { ArrayList arrayList = (ArrayList) field; if (index < arrayList.size()) { @@ -94,34 +111,83 @@ private Object getEntryFromArray(CDAEntry parentEntry, String arrayFieldKey, int return null; } + /** + * Extract field from an entry and convert it its string representation. + * + * @param entry should contain expected field + * @param fieldKey id of field to be search inside entry + * @return string representation of the field + */ private Optional findContent(final CDAEntry entry, final String fieldKey) { + Matcher arrayMatcher = ARRAY_KEY_PATTERN.matcher(fieldKey); + if (arrayMatcher.find()) { + String arrayFieldKey = arrayMatcher.group(1); + return getFieldFromArray(entry, arrayMatcher).flatMap(field -> + getContent(entry, arrayFieldKey, field)); + } return getField(entry, fieldKey).flatMap(field -> - findContentTypeField(entry, fieldKey).flatMap(contentTypeField -> - getContentBasedOnType(field, contentTypeField))); + getContent(entry, fieldKey, field)); + } + + /** + * Try to get a field from input entry which is supposed to contain an array of fields. + * + * After pattern has been matched arrayMatcher contains a regexp group of key and index. + * E.g. after matching 'key[1]' two groups of 'key' and '1' are contained in matcher. + * + * They are later used to find 'key' field in entry and retrieve '1' (second) + * item from that field which is expected to form an array list. + * + * If the process fails empty optional object is returned. + * + * @param entry should contain expected array field + * @param arrayMatcher contains key and index groups after pattern has been matched + * @return matched field or empty optional object + */ + private Optional getFieldFromArray(final CDAEntry entry, final Matcher arrayMatcher) { + String arrayFieldKey = arrayMatcher.group(1); + int index = Integer.parseInt(arrayMatcher.group(2)); + return getField(entry, arrayFieldKey).map(field -> { + if (field instanceof ArrayList) { + ArrayList arrayList = (ArrayList) field; + if (index < arrayList.size()) { + return arrayList.get(index); + } + } + return null; + }); } private Optional getField(final CDAEntry entry, final String fieldKey) { return Optional.ofNullable(entry.getField(fieldKey)); } + private Optional getContent(CDAEntry entry, String fieldKey, Object field) { + return findContentTypeField(entry, fieldKey).flatMap(contentTypeField -> + getContentBasedOnType(field, contentTypeField)); + } + + /** + * Find content type of an entry and validate if it's supported by this implementation. + */ private Optional findContentTypeField(final CDAEntry entry, final String fieldKey) { return entry.contentType().fields().stream() - .filter(field -> field.id().equals(fieldKey) && FieldTypes.ALL_SUPPORTED.contains(field.type())) + .filter(field -> field.id().equals(fieldKey) && isSupported(field.type())) .findAny(); } /** * Convert content of the field to String if possible. * - * @param entryField object to convert to string - * @param contentTypeField information about object's type + * @param field object to convert to string + * @param contentType information about field's type * @return content of the field in String representation if possible */ - private Optional getContentBasedOnType(final Object entryField, final CDAField contentTypeField) { - if (FieldTypes.CONVERTABLE_TO_STRING.contains(contentTypeField.type())) { - return Optional.of(String.valueOf(entryField)); - } else if (FieldTypes.LINK_ASSET.equals(contentTypeField.linkType())) { - return Optional.ofNullable(((CDAAsset) entryField).url()); + private Optional getContentBasedOnType(final Object field, final CDAField contentType) { + if (hasStringRepresentation(contentType)) { + return Optional.of(String.valueOf(field)); + } else if (isAsset(contentType)) { + return Optional.ofNullable(((CDAAsset) field).url()); } return Optional.empty(); } diff --git a/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/models/FieldType.java b/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/models/FieldType.java new file mode 100644 index 0000000..e778920 --- /dev/null +++ b/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/models/FieldType.java @@ -0,0 +1,75 @@ +package com.commercetools.sunrise.cms.contentful.models; + +import com.contentful.java.cda.CDAField; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +public enum FieldType { + BOOLEAN("Boolean", true), + DATE("Date", true), + INTEGER("Integer", true), + NUMBER("Number", true), + SYMBOL("Symbol", true), + TEXT("Text", true), + LOCATION("Location", true), + LINK("Link", false), + ASSET("Asset", false), + ARRAY("Array", false); + + private static final Set WITH_STRING_REPRESENTATION = Collections.unmodifiableSet( + Arrays.stream(values()) + .filter(contentType -> contentType.hasStringRepresentation) + .map(FieldType::getType) + .collect(Collectors.toSet())); + + private static final Set SUPPORTED_TYPES = Collections.unmodifiableSet( + Arrays.stream(values()) + .map(FieldType::getType) + .collect(Collectors.toSet())); + + private final String type; + private final boolean hasStringRepresentation; + + FieldType(String type, boolean hasStringRepresentation) { + this.type = type; + this.hasStringRepresentation = hasStringRepresentation; + } + + public String getType() { + return type; + } + + public static boolean isSupported(String type) { + return SUPPORTED_TYPES.contains(type); + } + + public static boolean hasStringRepresentation(final CDAField contentType) { + if (WITH_STRING_REPRESENTATION.contains(contentType.type())) { + return true; + } + if (ARRAY.getType().equals(contentType.type())) { + Object type = contentType.items().get("type"); + if (type != null && type instanceof String && WITH_STRING_REPRESENTATION.contains(type)) { + return true; + } + } + return false; + } + + public static boolean isAsset(final CDAField contentType) { + if (ASSET.getType().equals(contentType.linkType())) { + return true; + } + if (ARRAY.getType().equals(contentType.type())) { + Object linkType = contentType.items().get("linkType"); + if (Objects.equals(linkType, ASSET.getType())) { + return true; + } + } + return false; + } +} diff --git a/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/models/FieldTypes.java b/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/models/FieldTypes.java deleted file mode 100644 index 9ecfa02..0000000 --- a/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/models/FieldTypes.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.commercetools.sunrise.cms.contentful.models; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public final class FieldTypes { - public static final String BOOLEAN = "Boolean"; - public static final String DATE = "Date"; - public static final String INTEGER = "Integer"; - public static final String LINK = "Link"; - public static final String NUMBER = "Number"; - public static final String SYMBOL = "Symbol"; - public static final String TEXT = "Text"; - public static final String LINK_ASSET = "Asset"; - public static final List CONVERTABLE_TO_STRING = Collections.unmodifiableList( - Arrays.asList(BOOLEAN, DATE, INTEGER, NUMBER, SYMBOL, TEXT)); - public static final List ALL_SUPPORTED = Collections.unmodifiableList( - new ArrayList(CONVERTABLE_TO_STRING) {{ - add(LINK); - }}); - - private FieldTypes() { - throw new AssertionError(); - } -} \ No newline at end of file From ea22d0946e67b455532829c135cae693132ad5ca Mon Sep 17 00:00:00 2001 From: Piotr Brandt Date: Fri, 27 Jan 2017 16:18:56 +0100 Subject: [PATCH 4/9] refactor field types handling --- .../cms/contentful/ContentfulCmsPage.java | 57 +++++++---------- .../cms/contentful/models/FieldType.java | 63 +++++++++---------- 2 files changed, 53 insertions(+), 67 deletions(-) diff --git a/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java b/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java index da37cbc..83a1866 100644 --- a/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java +++ b/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java @@ -1,7 +1,6 @@ package com.commercetools.sunrise.cms.contentful; import com.commercetools.sunrise.cms.CmsPage; -import com.contentful.java.cda.CDAAsset; import com.contentful.java.cda.CDAEntry; import com.contentful.java.cda.CDAField; import org.apache.commons.lang3.StringUtils; @@ -10,9 +9,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import static com.commercetools.sunrise.cms.contentful.models.FieldType.hasStringRepresentation; -import static com.commercetools.sunrise.cms.contentful.models.FieldType.isAsset; -import static com.commercetools.sunrise.cms.contentful.models.FieldType.isSupported; +import static com.commercetools.sunrise.cms.contentful.models.FieldType.ARRAY; +import static com.commercetools.sunrise.cms.contentful.models.FieldType.getToStringStrategy; import static java.util.Arrays.copyOfRange; import static org.apache.commons.lang3.StringUtils.split; @@ -122,11 +120,13 @@ private Optional findContent(final CDAEntry entry, final String fieldKey Matcher arrayMatcher = ARRAY_KEY_PATTERN.matcher(fieldKey); if (arrayMatcher.find()) { String arrayFieldKey = arrayMatcher.group(1); - return getFieldFromArray(entry, arrayMatcher).flatMap(field -> - getContent(entry, arrayFieldKey, field)); + return findContentTypeField(entry, arrayFieldKey, true).flatMap(contentTypeField -> + getFieldFromArray(entry, arrayMatcher).map(field -> + getContentBasedOnType(field, contentTypeField))); } - return getField(entry, fieldKey).flatMap(field -> - getContent(entry, fieldKey, field)); + return findContentTypeField(entry, fieldKey, false).flatMap(contentTypeField -> + Optional.ofNullable(entry.getField(fieldKey)).map(field -> + getContentBasedOnType(field, contentTypeField))); } /** @@ -147,32 +147,25 @@ private Optional findContent(final CDAEntry entry, final String fieldKey private Optional getFieldFromArray(final CDAEntry entry, final Matcher arrayMatcher) { String arrayFieldKey = arrayMatcher.group(1); int index = Integer.parseInt(arrayMatcher.group(2)); - return getField(entry, arrayFieldKey).map(field -> { - if (field instanceof ArrayList) { - ArrayList arrayList = (ArrayList) field; - if (index < arrayList.size()) { - return arrayList.get(index); - } + Object field = entry.getField(arrayFieldKey); + Object item = null; + if (field != null && field instanceof ArrayList) { + ArrayList arrayList = (ArrayList) field; + if (index < arrayList.size()) { + item = arrayList.get(index); } - return null; - }); - } - - private Optional getField(final CDAEntry entry, final String fieldKey) { - return Optional.ofNullable(entry.getField(fieldKey)); - } - - private Optional getContent(CDAEntry entry, String fieldKey, Object field) { - return findContentTypeField(entry, fieldKey).flatMap(contentTypeField -> - getContentBasedOnType(field, contentTypeField)); + } + return Optional.ofNullable(item); } /** * Find content type of an entry and validate if it's supported by this implementation. */ - private Optional findContentTypeField(final CDAEntry entry, final String fieldKey) { + private Optional findContentTypeField(final CDAEntry entry, final String fieldKey, + boolean arrayExpected) { return entry.contentType().fields().stream() - .filter(field -> field.id().equals(fieldKey) && isSupported(field.type())) + .filter(field -> field.id().equals(fieldKey)) + .filter(field -> arrayExpected == ARRAY.type().equals(field.type())) .findAny(); } @@ -183,13 +176,7 @@ private Optional findContentTypeField(final CDAEntry entry, final Stri * @param contentType information about field's type * @return content of the field in String representation if possible */ - private Optional getContentBasedOnType(final Object field, final CDAField contentType) { - if (hasStringRepresentation(contentType)) { - return Optional.of(String.valueOf(field)); - } else if (isAsset(contentType)) { - return Optional.ofNullable(((CDAAsset) field).url()); - } - return Optional.empty(); + private String getContentBasedOnType(final Object field, final CDAField contentType) { + return getToStringStrategy(contentType).apply(field); } - } diff --git a/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/models/FieldType.java b/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/models/FieldType.java index e778920..afae7eb 100644 --- a/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/models/FieldType.java +++ b/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/models/FieldType.java @@ -1,11 +1,12 @@ package com.commercetools.sunrise.cms.contentful.models; +import com.contentful.java.cda.CDAAsset; import com.contentful.java.cda.CDAField; import java.util.Arrays; import java.util.Collections; -import java.util.Objects; import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; public enum FieldType { @@ -23,12 +24,7 @@ public enum FieldType { private static final Set WITH_STRING_REPRESENTATION = Collections.unmodifiableSet( Arrays.stream(values()) .filter(contentType -> contentType.hasStringRepresentation) - .map(FieldType::getType) - .collect(Collectors.toSet())); - - private static final Set SUPPORTED_TYPES = Collections.unmodifiableSet( - Arrays.stream(values()) - .map(FieldType::getType) + .map(FieldType::type) .collect(Collectors.toSet())); private final String type; @@ -39,37 +35,40 @@ public enum FieldType { this.hasStringRepresentation = hasStringRepresentation; } - public String getType() { + public String type() { return type; } - public static boolean isSupported(String type) { - return SUPPORTED_TYPES.contains(type); + public static Function getToStringStrategy(final CDAField contentType) { + if (hasStringRepresentation(getType(contentType))) { + return String::valueOf; + } else if (isAsset(getLinkType(contentType))) { + return field -> ((CDAAsset) field).url(); + } + return field -> null; } - public static boolean hasStringRepresentation(final CDAField contentType) { - if (WITH_STRING_REPRESENTATION.contains(contentType.type())) { - return true; - } - if (ARRAY.getType().equals(contentType.type())) { - Object type = contentType.items().get("type"); - if (type != null && type instanceof String && WITH_STRING_REPRESENTATION.contains(type)) { - return true; - } - } - return false; + private static boolean hasStringRepresentation(final String type) { + return WITH_STRING_REPRESENTATION.contains(type); } - public static boolean isAsset(final CDAField contentType) { - if (ASSET.getType().equals(contentType.linkType())) { - return true; - } - if (ARRAY.getType().equals(contentType.type())) { - Object linkType = contentType.items().get("linkType"); - if (Objects.equals(linkType, ASSET.getType())) { - return true; - } - } - return false; + private static String getType(final CDAField contentType) { + return isArray(contentType) ? castToString(contentType.items().get("type")) : contentType.type(); + } + + private static String getLinkType(final CDAField contentType) { + return isArray(contentType) ? castToString(contentType.items().get("linkType")) : contentType.linkType(); + } + + private static boolean isAsset(final String linkType) { + return ASSET.type().equals(linkType); + } + + private static boolean isArray(final CDAField contentType) { + return ARRAY.type().equals(contentType.type()); + } + + private static String castToString(final Object type) { + return type != null && type instanceof String ? (String) type : null; } } From 03bd2db53fc46c1e4ddd28d2c22cb8041295dd7e Mon Sep 17 00:00:00 2001 From: Piotr Brandt Date: Mon, 30 Jan 2017 18:02:39 +0100 Subject: [PATCH 5/9] extend integration tests after providing support for new models on contentful --- .../contentful/ContentfulCmsServiceIT.java | 198 +++++++++++++++--- 1 file changed, 174 insertions(+), 24 deletions(-) diff --git a/cms-contentful/it/com/commercetools/sunrise/cms/contentful/ContentfulCmsServiceIT.java b/cms-contentful/it/com/commercetools/sunrise/cms/contentful/ContentfulCmsServiceIT.java index 7d2f9ed..34f2c17 100644 --- a/cms-contentful/it/com/commercetools/sunrise/cms/contentful/ContentfulCmsServiceIT.java +++ b/cms-contentful/it/com/commercetools/sunrise/cms/contentful/ContentfulCmsServiceIT.java @@ -2,10 +2,8 @@ import com.commercetools.sunrise.cms.CmsPage; import com.commercetools.sunrise.cms.CmsServiceException; -import org.junit.Before; import org.junit.Test; -import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Optional; @@ -14,11 +12,13 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.ThrowableAssert.catchThrowable; public class ContentfulCmsServiceIT { - private static final List SUPPORTED_LOCALES = Collections.singletonList(Locale.GERMANY); + private static final List SUPPORTED_LOCALES = singletonList(Locale.GERMANY); // credentials for contentful demo account private static final String IT_PREFIX = "CONTENTFUL_"; @@ -26,7 +26,6 @@ public class ContentfulCmsServiceIT { private static final String IT_CF_TOKEN = IT_PREFIX + "TOKEN"; private static final String PAGE_TYPE_NAME = "page"; private static final String PAGE_TYPE_ID_FIELD_NAME = "slug"; - private ContentfulCmsService contentfulCmsService; private static String spaceId() { return getValueForEnvVar(IT_CF_SPACE_ID); @@ -36,11 +35,6 @@ private static String token() { return getValueForEnvVar(IT_CF_TOKEN); } - @Before - public void setUp() throws Exception { - contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), PAGE_TYPE_NAME, PAGE_TYPE_ID_FIELD_NAME); - } - @Test public void whenCouldNotFetchEntry_thenThrowException() throws Exception { final ContentfulCmsService cmsService = ContentfulCmsService.of("", "", PAGE_TYPE_NAME, PAGE_TYPE_ID_FIELD_NAME); @@ -52,65 +46,221 @@ public void whenCouldNotFetchEntry_thenThrowException() throws Exception { } @Test - public void whenAskForExistingStringContentThenGet() throws Exception { + public void whenAskForExistingStringContent_thenGet() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), PAGE_TYPE_NAME, PAGE_TYPE_ID_FIELD_NAME); + Optional content = waitAndGet(contentfulCmsService.page("finn", SUPPORTED_LOCALES)); - assertThat(content).isPresent(); + assertThat(content).isPresent(); assertThat(content.get().field("pageContent.description")).contains("Fearless Abenteurer! Verteidiger von Pfannkuchen."); } @Test - public void whenAskForExistingStringContentAndLocalesAreEmptyThenGetDefaultLocaleContent() throws Exception { - Optional content = waitAndGet(contentfulCmsService.page("finn", Collections.emptyList())); - assertThat(content).isPresent(); + public void whenAskForExistingStringContentAndLocalesAreEmpty_thenGetDefaultLocaleContent() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), PAGE_TYPE_NAME, PAGE_TYPE_ID_FIELD_NAME); + Optional content = waitAndGet(contentfulCmsService.page("finn", emptyList())); + + assertThat(content).isPresent(); assertThat(content.get().field("pageContent.description")).contains("Fearless Abenteurer! Verteidiger von Pfannkuchen."); } @Test - public void whenAskForExistingStringContentAndLocalesAreNullThenGetDefaultLocaleContent() throws Exception { + public void whenAskForExistingStringContentAndLocalesAreNull_thenGetDefaultLocaleContent() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), PAGE_TYPE_NAME, PAGE_TYPE_ID_FIELD_NAME); + Optional content = waitAndGet(contentfulCmsService.page("finn", null)); - assertThat(content).isPresent(); + assertThat(content).isPresent(); assertThat(content.get().field("pageContent.description")).contains("Fearless Abenteurer! Verteidiger von Pfannkuchen."); } @Test - public void whenAskForExistingStringContentWithNotDefaultLocaleThenGet() throws Exception { - Optional content = waitAndGet(contentfulCmsService.page("finn", Collections.singletonList(Locale.ENGLISH))); - assertThat(content).isPresent(); + public void whenAskForExistingStringContentWithNotDefaultLocale_thenGetDefaultLocaleContent() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), PAGE_TYPE_NAME, PAGE_TYPE_ID_FIELD_NAME); + + Optional content = waitAndGet(contentfulCmsService.page("finn", singletonList(Locale.ENGLISH))); + assertThat(content).isPresent(); assertThat(content.get().field("pageContent.description")).contains("Fearless adventurer! Defender of pancakes."); } @Test - public void whenAskForExistingStringContentWithNotDefinedLocaleThenNotPresent() throws Exception { - Optional content = waitAndGet(contentfulCmsService.page("finn", Collections.singletonList(Locale.ITALIAN))); + public void whenAskForExistingStringContentWithNotDefinedLocale_thenReturnEmpty() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), PAGE_TYPE_NAME, PAGE_TYPE_ID_FIELD_NAME); + + Optional content = waitAndGet(contentfulCmsService.page("finn", singletonList(Locale.ITALIAN))); + assertThat(content).isEmpty(); } @Test - public void whenAskForNotExistingStringContentThenNotPresent() throws Exception { + public void whenAskForNotExistingStringContent_thenReturnEmpty() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), PAGE_TYPE_NAME, PAGE_TYPE_ID_FIELD_NAME); Optional content = waitAndGet(contentfulCmsService.page("finn", SUPPORTED_LOCALES)); assertThat(content).isPresent(); assertThat(content.get().field("pageContent.notExistingField")).isEmpty(); } @Test - public void whenAskForExistingAssetContentThenGet() throws Exception { + public void whenAskForExistingAssetContent_thenGet() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), PAGE_TYPE_NAME, PAGE_TYPE_ID_FIELD_NAME); + Optional content = waitAndGet(contentfulCmsService.page("jacke", SUPPORTED_LOCALES)); + assertThat(content).isPresent(); assertThat(content.get().fieldOrEmpty("pageContent.image")).isEqualToIgnoringCase("//images.contentful.com/l6chdlzlf8jn/2iVeCh1FGoy00Oq8WEI2aI/93c3f0841fcf59743f57e238f6ed67aa/jake.png"); } @Test - public void whenAskForNotExistingAssetContentThenNotPresent() throws Exception { + public void whenAskForNotExistingAssetContent_thenReturnEmpty() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), PAGE_TYPE_NAME, PAGE_TYPE_ID_FIELD_NAME); + Optional content = waitAndGet(contentfulCmsService.page("jacke", SUPPORTED_LOCALES)); + assertThat(content).isPresent(); assertThat(content.get().fieldOrEmpty("pageContent.notExistingAsset")).isEmpty(); } + @Test + public void whenAskForContentInArray_thenGetElement() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), "finn", PAGE_TYPE_ID_FIELD_NAME); + Optional content = contentfulCmsService.page("finn", emptyList()).toCompletableFuture().get(5, TimeUnit.SECONDS); + + assertThat(content).isPresent(); + Optional field = content.get().field("array[0].name"); + assertThat(field).isPresent(); + assertThat(field.get()).isEqualTo("author1"); + } + + @Test + public void whenAskForContentInArrayOutsideTheScope_thenReturnEmpty() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), "finn", PAGE_TYPE_ID_FIELD_NAME); + Optional content = contentfulCmsService.page("finn", emptyList()).toCompletableFuture().get(5, TimeUnit.SECONDS); + + assertThat(content).isPresent(); + Optional field = content.get().field("array[4].name"); + assertThat(field).isNotPresent(); + } + + @Test + public void whenAskForContentInNestedArray_thenGetElement() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), "finn", PAGE_TYPE_ID_FIELD_NAME); + Optional content = contentfulCmsService.page("finn", emptyList()).toCompletableFuture().get(5, TimeUnit.SECONDS); + + assertThat(content).isPresent(); + Optional field = content.get().field("array[1].images[1].photo"); + assertThat(field).isPresent(); + assertThat(field.get()).isEqualTo("//images.contentful.com/l6chdlzlf8jn/3slBXXe6WcsiM46OuEuIKe/bab374a315d1825c111d9d89843cafc0/logo.gif"); + } + + @Test + public void whenAskForTextContentArray_thenGetElement() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), "finn", PAGE_TYPE_ID_FIELD_NAME); + + Optional content = contentfulCmsService.page("finn", emptyList()).toCompletableFuture().get(5, TimeUnit.SECONDS); + + assertThat(content).isPresent(); + Optional field = content.get().field("array[2].simpleText"); + assertThat(field).isPresent(); + assertThat(field.get()).isEqualTo("simpleText1"); + } + + @Test + public void whenAskForLocation_thenGetLocationField() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), "finn", PAGE_TYPE_ID_FIELD_NAME); + + Optional content = contentfulCmsService.page("finn", emptyList()).toCompletableFuture().get(5, TimeUnit.SECONDS); + + assertThat(content).isPresent(); + Optional field = content.get().field("locationField"); + assertThat(field).isPresent(); + assertThat(field.get()).isEqualTo("{lon=19.62158203125, lat=51.37199469960235}"); + } + + @Test + public void whenAskForContentInMediaField_thenGetUrlField() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), "finn", PAGE_TYPE_ID_FIELD_NAME); + + Optional content = contentfulCmsService.page("finn", emptyList()).toCompletableFuture().get(5, TimeUnit.SECONDS); + + assertThat(content).isPresent(); + Optional field = content.get().field("mediaOneFile"); + assertThat(field).isPresent(); + assertThat(field.get()).isEqualTo("//images.contentful.com/l6chdlzlf8jn/2m1NzbeXYUksOGIwceEy0U/4e3cc53a96313a4bd822777af78a3b4d/some-5.jpg"); + } + + @Test + public void whenAskForContentInMediaArray_thenGetUrlElements() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), "finn", PAGE_TYPE_ID_FIELD_NAME); + + Optional content = contentfulCmsService.page("finn", emptyList()).toCompletableFuture().get(5, TimeUnit.SECONDS); + + assertThat(content).isPresent(); + Optional field = content.get().field("mediaManyFiles[0]"); + assertThat(field).isPresent(); + assertThat(field.get()).isEqualTo("//images.contentful.com/l6chdlzlf8jn/6j9p38phC0oU0g42aqUSc4/2eb0c261bc13353ed867b13076af6b1f/logo.gif"); + + field = content.get().field("mediaManyFiles[1]"); + assertThat(field).isPresent(); + assertThat(field.get()).isEqualTo("//images.contentful.com/l6chdlzlf8jn/27BPx56xMcuGKe8uk8Auss/335581cd9daf3e9d0de254313e36d43b/some-5.jpg"); + } + + @Test + public void whenAskForContentInArrayOutsideTheScope_thenGet() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), "finn", PAGE_TYPE_ID_FIELD_NAME); + Optional content = contentfulCmsService.page("finn", emptyList()).toCompletableFuture().get(5, TimeUnit.SECONDS); + + assertThat(content).isPresent(); + Optional field = content.get().field("array[3].textArrayField"); + assertThat(field).isNotPresent(); + } + + @Test + public void whenAskForContentWithGermanOrEmptyLocales_thenGetGermanTranslation() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), "finn", PAGE_TYPE_ID_FIELD_NAME); + + Optional content = contentfulCmsService.page("finn", SUPPORTED_LOCALES).toCompletableFuture().get(5, TimeUnit.SECONDS); + + assertThat(content).isPresent(); + Optional field = content.get().field("array[3].textArrayField[1]"); + assertThat(field).isPresent(); + assertThat(field.get()).isEqualTo("zwei"); + + content = contentfulCmsService.page("finn", emptyList()).toCompletableFuture().get(5, TimeUnit.SECONDS); + + assertThat(content).isPresent(); + field = content.get().field("array[3].textArrayField[1]"); + assertThat(field).isPresent(); + assertThat(field.get()).isEqualTo("zwei"); + + content = waitAndGet(contentfulCmsService.page("finn", singletonList(Locale.ITALIAN))); + + assertThat(content).isNotPresent(); + } + + @Test + public void whenAskForContentWithNonExistingLocales_thenReturnEmpty() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), "finn", PAGE_TYPE_ID_FIELD_NAME); + + Optional content = waitAndGet(contentfulCmsService.page("finn", singletonList(Locale.ITALIAN))); + + assertThat(content).isNotPresent(); + } + + @Test + public void whenAskForContentWithEnglishTranslation_thenGetEnglishTranslation() throws Exception { + ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), "finn", PAGE_TYPE_ID_FIELD_NAME); + + Optional content = contentfulCmsService.page("finn", singletonList(Locale.ENGLISH)).toCompletableFuture().get(5, TimeUnit.SECONDS); + + assertThat(content).isPresent(); + Optional field = content.get().field("array[3].textArrayField[1]"); + assertThat(field).isPresent(); + assertThat(field.get()).isEqualTo("two"); + } + private T waitAndGet(final CompletionStage stage) throws InterruptedException, ExecutionException, TimeoutException { return stage.toCompletableFuture().get(5, TimeUnit.SECONDS); } From fe261baf664ef4a19865b117c9d3fab3783b3e50 Mon Sep 17 00:00:00 2001 From: Piotr Brandt Date: Tue, 31 Jan 2017 16:35:55 +0100 Subject: [PATCH 6/9] extend unit tests after providing support for new models on contentful --- .../cms/contentful/ContentfulCmsPageTest.java | 99 +++++++++++++------ 1 file changed, 71 insertions(+), 28 deletions(-) diff --git a/cms-contentful/src/test/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPageTest.java b/cms-contentful/src/test/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPageTest.java index 02fc129..d3ec633 100644 --- a/cms-contentful/src/test/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPageTest.java +++ b/cms-contentful/src/test/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPageTest.java @@ -4,13 +4,13 @@ import com.contentful.java.cda.CDAContentType; import com.contentful.java.cda.CDAEntry; import com.contentful.java.cda.CDAField; -import org.junit.Before; import org.junit.Test; import java.util.*; -import static com.commercetools.sunrise.cms.contentful.models.FieldTypes.*; +import static com.commercetools.sunrise.cms.contentful.models.FieldType.*; import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -19,16 +19,11 @@ public class ContentfulCmsPageTest { private static final List SUPPORTED_LOCALES = asList(Locale.GERMANY, Locale.US); private static final String FIELD_NAME = "leftTop"; private static final String CONTENT_VALUE = "Content of left top"; - private final CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, CONTENT_VALUE); - private ContentfulCmsPage contentfulCmsPage; - - @Before - public void setUp() throws Exception { - contentfulCmsPage = new ContentfulCmsPage(mockCdaEntry, SUPPORTED_LOCALES); - } @Test public void whenEntryDoesNotHaveRequiredField_thenReturnOptionalEmpty() throws Exception { + CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, CONTENT_VALUE); + ContentfulCmsPage contentfulCmsPage = new ContentfulCmsPage(mockCdaEntry, SUPPORTED_LOCALES); final String notMatchingFieldName = "notMatchingFieldName"; final Optional content = contentfulCmsPage.field(notMatchingFieldName); @@ -37,6 +32,8 @@ public void whenEntryDoesNotHaveRequiredField_thenReturnOptionalEmpty() throws E @Test public void whenEntryExistsInSupportedLanguage_thenReturnIt() throws Exception { + CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, CONTENT_VALUE); + ContentfulCmsPage contentfulCmsPage = new ContentfulCmsPage(mockCdaEntry, SUPPORTED_LOCALES); final Optional content = contentfulCmsPage.field(FIELD_NAME); assertThat(content).contains("Content of left top"); @@ -44,7 +41,7 @@ public void whenEntryExistsInSupportedLanguage_thenReturnIt() throws Exception { @Test public void whenEntryFieldTypeIsText_thenReturnOptionalString() throws Exception { - final CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, CONTENT_VALUE, TEXT); + CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, CONTENT_VALUE); final ContentfulCmsPage contentfulCmsPage = new ContentfulCmsPage(mockCdaEntry, SUPPORTED_LOCALES); final Optional content = contentfulCmsPage.field(FIELD_NAME); @@ -54,7 +51,7 @@ public void whenEntryFieldTypeIsText_thenReturnOptionalString() throws Exception @Test public void whenEntryFieldTypeIsDate_thenReturnOptionalString() throws Exception { final String fieldContent = "2015-11-06T09:45:27"; - final CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, fieldContent, DATE); + final CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, fieldContent, DATE.type()); final ContentfulCmsPage contentfulCmsPage = new ContentfulCmsPage(mockCdaEntry, SUPPORTED_LOCALES); final Optional content = contentfulCmsPage.field(FIELD_NAME); @@ -64,7 +61,7 @@ public void whenEntryFieldTypeIsDate_thenReturnOptionalString() throws Exception @Test public void whenEntryFieldTypeIsInteger_thenReturnOptionalString() throws Exception { final int fieldContent = 13; - final CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, fieldContent, INTEGER); + final CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, fieldContent, INTEGER.type()); final ContentfulCmsPage contentfulCmsPage = new ContentfulCmsPage(mockCdaEntry, SUPPORTED_LOCALES); final Optional content = contentfulCmsPage.field(FIELD_NAME); @@ -74,7 +71,7 @@ public void whenEntryFieldTypeIsInteger_thenReturnOptionalString() throws Except @Test public void whenEntryFieldTypeIsNumber_thenReturnOptionalString() throws Exception { final double fieldContent = 3.14; - final CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, fieldContent, NUMBER); + final CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, fieldContent, NUMBER.type()); final ContentfulCmsPage contentfulCmsPage = new ContentfulCmsPage(mockCdaEntry, SUPPORTED_LOCALES); final Optional content = contentfulCmsPage.field(FIELD_NAME); @@ -84,7 +81,7 @@ public void whenEntryFieldTypeIsNumber_thenReturnOptionalString() throws Excepti @Test public void whenEntryFieldTypeIsBoolean_thenReturnOptionalString() throws Exception { final boolean fieldContent = true; - final CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, fieldContent, BOOLEAN); + final CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, fieldContent, BOOLEAN.type()); final ContentfulCmsPage contentfulCmsPage = new ContentfulCmsPage(mockCdaEntry, SUPPORTED_LOCALES); final Optional content = contentfulCmsPage.field(FIELD_NAME); @@ -96,7 +93,7 @@ public void whenEntryFieldTypeIsLinkAsset_thenReturnOptionalString() throws Exce final String fieldContent = "//some.url"; final CDAAsset mockAsset = mock(CDAAsset.class); when(mockAsset.url()).thenReturn(fieldContent); - final CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, mockAsset, LINK, true); + final CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, mockAsset, LINK.type(), true); final ContentfulCmsPage contentfulCmsPage = new ContentfulCmsPage(mockCdaEntry, SUPPORTED_LOCALES); final Optional content = contentfulCmsPage.field(FIELD_NAME); @@ -108,7 +105,7 @@ public void whenEntryFieldTypeLinkIsOtherThanAsset_thenReturnOptionalEmpty() thr final String fieldContent = "//some.url"; final CDAAsset mockAsset = mock(CDAAsset.class); when(mockAsset.url()).thenReturn(fieldContent); - final CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, mockAsset, LINK, false); + final CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, mockAsset, LINK.type(), false); final ContentfulCmsPage contentfulCmsPage = new ContentfulCmsPage(mockCdaEntry, SUPPORTED_LOCALES); final Optional content = contentfulCmsPage.field(FIELD_NAME); @@ -120,39 +117,85 @@ public void whenAssetHasNoUrl_thenReturnOptionalEmpty() throws Exception { final String fieldContent = null; final CDAAsset mockAsset = mock(CDAAsset.class); when(mockAsset.url()).thenReturn(fieldContent); - final CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, mockAsset, LINK, true); + final CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, mockAsset, LINK.type(), true); final ContentfulCmsPage contentfulCmsPage = new ContentfulCmsPage(mockCdaEntry, SUPPORTED_LOCALES); final Optional content = contentfulCmsPage.field(FIELD_NAME); assertThat(content).isEmpty(); } - private CDAEntry mockEntry(final String fieldName, - final String fieldContent) { - return mockEntry(fieldName, fieldContent, SYMBOL, false); + @Test + public void whenEntryFieldTypeIsLocation_thenReturnOptionalString() throws Exception { + Object fieldContent = "{lon=19.62158203125, lat=51.37199469960235}"; + CDAEntry mockCdaEntry = mockEntry(FIELD_NAME, fieldContent, LOCATION.type()); + ContentfulCmsPage contentfulCmsPage = new ContentfulCmsPage(mockCdaEntry, SUPPORTED_LOCALES); + + Optional content = contentfulCmsPage.field(FIELD_NAME); + + assertThat(content.isPresent()); + assertThat(content.get()).isEqualTo("{lon=19.62158203125, lat=51.37199469960235}"); + } + + @Test + public void whenEntryFieldTypeIsArrayOfText_thenReturnOptionalString() throws Exception { + CDAEntry mockCdaEntry = mockEntry("textArrayField", createArray("two"), TEXT.type(), false); + ContentfulCmsPage contentfulCmsPage = new ContentfulCmsPage(mockCdaEntry, singletonList(Locale.ENGLISH)); + + Optional content = contentfulCmsPage.field("textArrayField[1]"); + + assertThat(content.isPresent()); + assertThat(content.get()).isEqualTo("two"); + } + + @Test + public void whenEntryFieldTypeIsArrayOfLinkAssetsInsideArrayEntry_thenReturnOptionalString() throws Exception { + CDAAsset mockAsset = mock(CDAAsset.class); + when(mockAsset.url()).thenReturn("//url"); + CDAEntry mockCdaEntry = mockEntry("assetArrayField", createArray(mockAsset), ASSET.type(), false); + CDAEntry mockCdaArrayEntry = mockEntry("array", createArray(mockCdaEntry), ARRAY.type(), false); + ContentfulCmsPage contentfulCmsPage = new ContentfulCmsPage(mockCdaArrayEntry, singletonList(Locale.ENGLISH)); + + Optional content = contentfulCmsPage.field("array[1].assetArrayField[1]"); + + assertThat(content.isPresent()); + assertThat(content.get()).isEqualTo("//url"); + } + + private ArrayList createArray(Object object) { + ArrayList array = new ArrayList<>(); + array.add(new Object()); + array.add(object); + array.add(new Object()); + return array; + } + + private CDAEntry mockEntry(final String fieldName, final String fieldContent) { + return mockEntry(fieldName, fieldContent, SYMBOL.type(), false); } - private CDAEntry mockEntry(final String fieldName, - final Object fieldContent, final String fieldType) { + private CDAEntry mockEntry(final String fieldName, final Object fieldContent, final String fieldType) { return mockEntry(fieldName, fieldContent, fieldType, false); } - private CDAEntry mockEntry(final String fieldName, - final Object fieldContent, final String fieldType, - final Boolean isLinkedAsset) { + private CDAEntry mockEntry(final String fieldName, final Object fieldContent, final String fieldType, final Boolean isLinkedAsset) { CDAEntry mockCdaEntry = mock(CDAEntry.class); CDAField mockCdaField = mock(CDAField.class); // mock entry type CDAContentType mockContentType = mock(CDAContentType.class); when(mockCdaEntry.contentType()).thenReturn(mockContentType); - when(mockCdaField.type()).thenReturn(fieldType); - when(mockCdaField.linkType()).thenReturn(isLinkedAsset ? LINK_ASSET : "otherLinkedType"); - when(mockCdaField.id()).thenReturn(FIELD_NAME); + when(mockCdaField.type()).thenReturn(fieldContent instanceof ArrayList ? ARRAY.type() : fieldType); + when(mockCdaField.linkType()).thenReturn(isLinkedAsset ? ASSET.type() : "otherLinkedType"); + when(mockCdaField.id()).thenReturn(fieldName); + Map items = new HashMap<>(); + items.put("type", fieldType); + items.put("linkType", fieldType); + when(mockCdaField.items()).thenReturn(items); when(mockContentType.fields()).thenReturn(Collections.singletonList(mockCdaField)); // mock field content Map mockRawFields = new HashMap<>(); + mockRawFields.put(fieldName, new Object()); when(mockCdaEntry.getField(fieldName)).thenReturn(fieldContent); when(mockCdaEntry.rawFields()).thenReturn(mockRawFields); From 4712e8be1d27166362de06e252ccf61994cf2e3c Mon Sep 17 00:00:00 2001 From: Piotr Brandt Date: Fri, 10 Feb 2017 16:45:43 +0100 Subject: [PATCH 7/9] improve type casting and provide more concise name of the method --- .../cms/contentful/ContentfulCmsPage.java | 22 ++++++++++--------- .../cms/contentful/models/FieldType.java | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java b/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java index 83a1866..1829a24 100644 --- a/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java +++ b/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/ContentfulCmsPage.java @@ -5,12 +5,13 @@ import com.contentful.java.cda.CDAField; import org.apache.commons.lang3.StringUtils; +import javax.annotation.Nullable; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.commercetools.sunrise.cms.contentful.models.FieldType.ARRAY; -import static com.commercetools.sunrise.cms.contentful.models.FieldType.getToStringStrategy; +import static com.commercetools.sunrise.cms.contentful.models.FieldType.toStringStrategy; import static java.util.Arrays.copyOfRange; import static org.apache.commons.lang3.StringUtils.split; @@ -94,15 +95,16 @@ private Optional findEntry(final String[] pathSegments) { * @param arrayMatcher contains key and index groups after pattern has been matched * @return matched entry or null */ + @Nullable private Object getEntryFromArray(final CDAEntry parentEntry, final Matcher arrayMatcher) { String arrayEntryKey = arrayMatcher.group(1); int index = Integer.parseInt(arrayMatcher.group(2)); if (parentEntry.rawFields().containsKey(arrayEntryKey)) { Object field = parentEntry.getField(arrayEntryKey); - if (field instanceof ArrayList) { - ArrayList arrayList = (ArrayList) field; - if (index < arrayList.size()) { - return arrayList.get(index); + if (field instanceof List) { + List list = (List) field; + if (index < list.size()) { + return list.get(index); } } } @@ -149,10 +151,10 @@ private Optional getFieldFromArray(final CDAEntry entry, final Matcher a int index = Integer.parseInt(arrayMatcher.group(2)); Object field = entry.getField(arrayFieldKey); Object item = null; - if (field != null && field instanceof ArrayList) { - ArrayList arrayList = (ArrayList) field; - if (index < arrayList.size()) { - item = arrayList.get(index); + if (field != null && field instanceof List) { + List list = (List) field; + if (index < list.size()) { + item = list.get(index); } } return Optional.ofNullable(item); @@ -177,6 +179,6 @@ private Optional findContentTypeField(final CDAEntry entry, final Stri * @return content of the field in String representation if possible */ private String getContentBasedOnType(final Object field, final CDAField contentType) { - return getToStringStrategy(contentType).apply(field); + return toStringStrategy(contentType).apply(field); } } diff --git a/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/models/FieldType.java b/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/models/FieldType.java index afae7eb..87a8e3b 100644 --- a/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/models/FieldType.java +++ b/cms-contentful/src/main/java/com/commercetools/sunrise/cms/contentful/models/FieldType.java @@ -39,7 +39,7 @@ public String type() { return type; } - public static Function getToStringStrategy(final CDAField contentType) { + public static Function toStringStrategy(final CDAField contentType) { if (hasStringRepresentation(getType(contentType))) { return String::valueOf; } else if (isAsset(getLinkType(contentType))) { From 7440f46900217b1e326b8080d2d049749899be79 Mon Sep 17 00:00:00 2001 From: Piotr Brandt Date: Fri, 10 Feb 2017 17:12:34 +0100 Subject: [PATCH 8/9] clean up it test --- .../contentful/ContentfulCmsServiceIT.java | 71 +++++++++---------- 1 file changed, 33 insertions(+), 38 deletions(-) diff --git a/cms-contentful/it/com/commercetools/sunrise/cms/contentful/ContentfulCmsServiceIT.java b/cms-contentful/it/com/commercetools/sunrise/cms/contentful/ContentfulCmsServiceIT.java index 34f2c17..e1fed3b 100644 --- a/cms-contentful/it/com/commercetools/sunrise/cms/contentful/ContentfulCmsServiceIT.java +++ b/cms-contentful/it/com/commercetools/sunrise/cms/contentful/ContentfulCmsServiceIT.java @@ -52,7 +52,8 @@ public void whenAskForExistingStringContent_thenGet() throws Exception { Optional content = waitAndGet(contentfulCmsService.page("finn", SUPPORTED_LOCALES)); assertThat(content).isPresent(); - assertThat(content.get().field("pageContent.description")).contains("Fearless Abenteurer! Verteidiger von Pfannkuchen."); + Optional field = content.get().field("pageContent.description"); + assertThat(field).hasValue("Fearless Abenteurer! Verteidiger von Pfannkuchen."); } @Test @@ -62,7 +63,8 @@ public void whenAskForExistingStringContentAndLocalesAreEmpty_thenGetDefaultLoca Optional content = waitAndGet(contentfulCmsService.page("finn", emptyList())); assertThat(content).isPresent(); - assertThat(content.get().field("pageContent.description")).contains("Fearless Abenteurer! Verteidiger von Pfannkuchen."); + Optional field = content.get().field("pageContent.description"); + assertThat(field).hasValue("Fearless Abenteurer! Verteidiger von Pfannkuchen."); } @Test @@ -72,7 +74,8 @@ public void whenAskForExistingStringContentAndLocalesAreNull_thenGetDefaultLocal Optional content = waitAndGet(contentfulCmsService.page("finn", null)); assertThat(content).isPresent(); - assertThat(content.get().field("pageContent.description")).contains("Fearless Abenteurer! Verteidiger von Pfannkuchen."); + Optional field = content.get().field("pageContent.description"); + assertThat(field).hasValue("Fearless Abenteurer! Verteidiger von Pfannkuchen."); } @Test @@ -82,7 +85,8 @@ public void whenAskForExistingStringContentWithNotDefaultLocale_thenGetDefaultLo Optional content = waitAndGet(contentfulCmsService.page("finn", singletonList(Locale.ENGLISH))); assertThat(content).isPresent(); - assertThat(content.get().field("pageContent.description")).contains("Fearless adventurer! Defender of pancakes."); + Optional field = content.get().field("pageContent.description"); + assertThat(field).hasValue("Fearless adventurer! Defender of pancakes."); } @Test @@ -91,15 +95,18 @@ public void whenAskForExistingStringContentWithNotDefinedLocale_thenReturnEmpty( Optional content = waitAndGet(contentfulCmsService.page("finn", singletonList(Locale.ITALIAN))); - assertThat(content).isEmpty(); + assertThat(content).isNotPresent(); } @Test public void whenAskForNotExistingStringContent_thenReturnEmpty() throws Exception { ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), PAGE_TYPE_NAME, PAGE_TYPE_ID_FIELD_NAME); + Optional content = waitAndGet(contentfulCmsService.page("finn", SUPPORTED_LOCALES)); + assertThat(content).isPresent(); - assertThat(content.get().field("pageContent.notExistingField")).isEmpty(); + Optional field = content.get().field("pageContent.notExistingField"); + assertThat(field).isNotPresent(); } @Test @@ -109,7 +116,8 @@ public void whenAskForExistingAssetContent_thenGet() throws Exception { Optional content = waitAndGet(contentfulCmsService.page("jacke", SUPPORTED_LOCALES)); assertThat(content).isPresent(); - assertThat(content.get().fieldOrEmpty("pageContent.image")).isEqualToIgnoringCase("//images.contentful.com/l6chdlzlf8jn/2iVeCh1FGoy00Oq8WEI2aI/93c3f0841fcf59743f57e238f6ed67aa/jake.png"); + String actual = content.get().fieldOrEmpty("pageContent.image"); + assertThat(actual).isEqualToIgnoringCase("//images.contentful.com/l6chdlzlf8jn/2iVeCh1FGoy00Oq8WEI2aI/93c3f0841fcf59743f57e238f6ed67aa/jake.png"); } @Test @@ -119,7 +127,8 @@ public void whenAskForNotExistingAssetContent_thenReturnEmpty() throws Exception Optional content = waitAndGet(contentfulCmsService.page("jacke", SUPPORTED_LOCALES)); assertThat(content).isPresent(); - assertThat(content.get().fieldOrEmpty("pageContent.notExistingAsset")).isEmpty(); + String actual = content.get().fieldOrEmpty("pageContent.notExistingAsset"); + assertThat(actual).isEmpty(); } @@ -130,16 +139,17 @@ public void whenAskForContentInArray_thenGetElement() throws Exception { assertThat(content).isPresent(); Optional field = content.get().field("array[0].name"); - assertThat(field).isPresent(); - assertThat(field.get()).isEqualTo("author1"); + assertThat(field).hasValue("author1"); } @Test public void whenAskForContentInArrayOutsideTheScope_thenReturnEmpty() throws Exception { ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), "finn", PAGE_TYPE_ID_FIELD_NAME); + Optional content = contentfulCmsService.page("finn", emptyList()).toCompletableFuture().get(5, TimeUnit.SECONDS); assertThat(content).isPresent(); + // array element consists of only 4 items Optional field = content.get().field("array[4].name"); assertThat(field).isNotPresent(); } @@ -147,12 +157,12 @@ public void whenAskForContentInArrayOutsideTheScope_thenReturnEmpty() throws Exc @Test public void whenAskForContentInNestedArray_thenGetElement() throws Exception { ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), "finn", PAGE_TYPE_ID_FIELD_NAME); + Optional content = contentfulCmsService.page("finn", emptyList()).toCompletableFuture().get(5, TimeUnit.SECONDS); assertThat(content).isPresent(); Optional field = content.get().field("array[1].images[1].photo"); - assertThat(field).isPresent(); - assertThat(field.get()).isEqualTo("//images.contentful.com/l6chdlzlf8jn/3slBXXe6WcsiM46OuEuIKe/bab374a315d1825c111d9d89843cafc0/logo.gif"); + assertThat(field).hasValue("//images.contentful.com/l6chdlzlf8jn/3slBXXe6WcsiM46OuEuIKe/bab374a315d1825c111d9d89843cafc0/logo.gif"); } @Test @@ -163,8 +173,7 @@ public void whenAskForTextContentArray_thenGetElement() throws Exception { assertThat(content).isPresent(); Optional field = content.get().field("array[2].simpleText"); - assertThat(field).isPresent(); - assertThat(field.get()).isEqualTo("simpleText1"); + assertThat(field).hasValue("simpleText1"); } @Test @@ -175,8 +184,7 @@ public void whenAskForLocation_thenGetLocationField() throws Exception { assertThat(content).isPresent(); Optional field = content.get().field("locationField"); - assertThat(field).isPresent(); - assertThat(field.get()).isEqualTo("{lon=19.62158203125, lat=51.37199469960235}"); + assertThat(field).hasValue("{lon=19.62158203125, lat=51.37199469960235}"); } @Test @@ -187,8 +195,7 @@ public void whenAskForContentInMediaField_thenGetUrlField() throws Exception { assertThat(content).isPresent(); Optional field = content.get().field("mediaOneFile"); - assertThat(field).isPresent(); - assertThat(field.get()).isEqualTo("//images.contentful.com/l6chdlzlf8jn/2m1NzbeXYUksOGIwceEy0U/4e3cc53a96313a4bd822777af78a3b4d/some-5.jpg"); + assertThat(field).hasValue("//images.contentful.com/l6chdlzlf8jn/2m1NzbeXYUksOGIwceEy0U/4e3cc53a96313a4bd822777af78a3b4d/some-5.jpg"); } @Test @@ -199,20 +206,20 @@ public void whenAskForContentInMediaArray_thenGetUrlElements() throws Exception assertThat(content).isPresent(); Optional field = content.get().field("mediaManyFiles[0]"); - assertThat(field).isPresent(); - assertThat(field.get()).isEqualTo("//images.contentful.com/l6chdlzlf8jn/6j9p38phC0oU0g42aqUSc4/2eb0c261bc13353ed867b13076af6b1f/logo.gif"); + assertThat(field).hasValue("//images.contentful.com/l6chdlzlf8jn/6j9p38phC0oU0g42aqUSc4/2eb0c261bc13353ed867b13076af6b1f/logo.gif"); field = content.get().field("mediaManyFiles[1]"); - assertThat(field).isPresent(); - assertThat(field.get()).isEqualTo("//images.contentful.com/l6chdlzlf8jn/27BPx56xMcuGKe8uk8Auss/335581cd9daf3e9d0de254313e36d43b/some-5.jpg"); + assertThat(field).hasValue("//images.contentful.com/l6chdlzlf8jn/27BPx56xMcuGKe8uk8Auss/335581cd9daf3e9d0de254313e36d43b/some-5.jpg"); } @Test - public void whenAskForContentInArrayOutsideTheScope_thenGet() throws Exception { + public void whenAskForArray_thenReturnEmpty() throws Exception { ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), "finn", PAGE_TYPE_ID_FIELD_NAME); + Optional content = contentfulCmsService.page("finn", emptyList()).toCompletableFuture().get(5, TimeUnit.SECONDS); assertThat(content).isPresent(); + // textArrayField is an array element so it can't be fetched as a whole Optional field = content.get().field("array[3].textArrayField"); assertThat(field).isNotPresent(); } @@ -225,30 +232,19 @@ public void whenAskForContentWithGermanOrEmptyLocales_thenGetGermanTranslation() assertThat(content).isPresent(); Optional field = content.get().field("array[3].textArrayField[1]"); - assertThat(field).isPresent(); - assertThat(field.get()).isEqualTo("zwei"); + assertThat(field).hasValue("zwei"); content = contentfulCmsService.page("finn", emptyList()).toCompletableFuture().get(5, TimeUnit.SECONDS); assertThat(content).isPresent(); field = content.get().field("array[3].textArrayField[1]"); - assertThat(field).isPresent(); - assertThat(field.get()).isEqualTo("zwei"); + assertThat(field).hasValue("zwei"); content = waitAndGet(contentfulCmsService.page("finn", singletonList(Locale.ITALIAN))); assertThat(content).isNotPresent(); } - @Test - public void whenAskForContentWithNonExistingLocales_thenReturnEmpty() throws Exception { - ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), "finn", PAGE_TYPE_ID_FIELD_NAME); - - Optional content = waitAndGet(contentfulCmsService.page("finn", singletonList(Locale.ITALIAN))); - - assertThat(content).isNotPresent(); - } - @Test public void whenAskForContentWithEnglishTranslation_thenGetEnglishTranslation() throws Exception { ContentfulCmsService contentfulCmsService = ContentfulCmsService.of(spaceId(), token(), "finn", PAGE_TYPE_ID_FIELD_NAME); @@ -257,8 +253,7 @@ public void whenAskForContentWithEnglishTranslation_thenGetEnglishTranslation() assertThat(content).isPresent(); Optional field = content.get().field("array[3].textArrayField[1]"); - assertThat(field).isPresent(); - assertThat(field.get()).isEqualTo("two"); + assertThat(field).hasValue("two"); } private T waitAndGet(final CompletionStage stage) throws InterruptedException, ExecutionException, TimeoutException { From babd5bbcdcac1e6b03be1381312603c2e5332896 Mon Sep 17 00:00:00 2001 From: Laura Luiz Date: Mon, 13 Feb 2017 14:15:07 +0100 Subject: [PATCH 9/9] Remove typo --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2967a8c..cb98ca0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ script: - "sbt test it:test unidoc" - if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then sbt "gitPublish target/javaunidoc https://$GH_TOKEN:x-oauth-basic@github.com/$TRAVIS_REPO_SLUG.git - javadoc sphere-oss automation@commercetools.de"; fi\ + javadoc sphere-oss automation@commercetools.de"; fi jdk: - oraclejdk8