diff options
| author | 2020-01-14 15:44:32 -0800 | |
|---|---|---|
| committer | 2020-01-24 15:36:20 -0800 | |
| commit | d0b1e1057f8a525e9f30cd9bc2e44522f0eb760e (patch) | |
| tree | 1d89882734748db9fe5a8f0be47ca17299c4ff66 | |
| parent | 7cc0c30d42ff5ae02b05946f38e32cb9d10bf0e1 (diff) | |
Adds ttl and support for index byte array in AppSearch.Document.
Bug: 143789408
Test: atest FrameworksCoreTests:android.app.appsearch
Change-Id: Ic3daf03ae232c0142d126c49e7e3ae7201076770
3 files changed, 176 insertions, 65 deletions
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchDocument.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchDocument.java index c396a291e9dc..66a90c25f7c4 100644 --- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchDocument.java +++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchDocument.java @@ -17,33 +17,33 @@ package android.app.appsearch; import android.annotation.CurrentTimeMillisLong; +import android.annotation.DurationMillisLong; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; -import android.os.Bundle; +import android.util.ArrayMap; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; +import com.android.internal.util.Preconditions; import com.google.android.icing.proto.DocumentProto; import com.google.android.icing.proto.PropertyProto; +import com.google.android.icing.protobuf.ByteString; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Objects; /** * Represents a document unit. * * <p>Documents are constructed via {@link AppSearchDocument.Builder}. - * * @hide */ -// TODO(b/143789408) set TTL for document in mProtoBuilder -// TODO(b/144518768) add visibility field if the stakeholders are comfortable with a no-op -// opt-in for this release. public class AppSearchDocument { private static final String TAG = "AppSearchDocument"; @@ -66,20 +66,21 @@ public class AppSearchDocument { @NonNull private final DocumentProto mProto; - /** Contains all properties in {@link #mProto} to support get properties via keys. */ + /** Contains all properties in {@link #mProto} to support getting properties via keys. */ @NonNull - private final Bundle mPropertyBundle; + private final Map<String, Object> mProperties; /** * Create a new {@link AppSearchDocument}. * @param proto Contains {@link AppSearchDocument} basic information (uri, schemaType etc) and * properties ordered by keys. - * @param propertyBundle Contains all properties in {@link #mProto} to support get - * properties via keys. + * @param propertiesMap Contains all properties in {@link #mProto} to support get properties + * via keys. */ - private AppSearchDocument(@NonNull DocumentProto proto, @NonNull Bundle propertyBundle) { - this.mProto = proto; - this.mPropertyBundle = propertyBundle; + private AppSearchDocument(@NonNull DocumentProto proto, + @NonNull Map<String, Object> propertiesMap) { + mProto = proto; + mProperties = propertiesMap; } /** @@ -88,12 +89,12 @@ public class AppSearchDocument { * <p>This method should be only used by constructor of a subclass. */ protected AppSearchDocument(@NonNull AppSearchDocument document) { - this(document.mProto, document.mPropertyBundle); + this(document.mProto, document.mProperties); } /** @hide */ AppSearchDocument(@NonNull DocumentProto documentProto) { - this(documentProto, new Bundle()); + this(documentProto, new ArrayMap<>()); for (int i = 0; i < documentProto.getPropertiesCount(); i++) { PropertyProto property = documentProto.getProperties(i); String name = property.getName(); @@ -102,38 +103,38 @@ public class AppSearchDocument { for (int j = 0; j < values.length; j++) { values[j] = property.getStringValues(j); } - mPropertyBundle.putStringArray(name, values); + mProperties.put(name, values); } else if (property.getInt64ValuesCount() > 0) { long[] values = new long[property.getInt64ValuesCount()]; for (int j = 0; j < values.length; j++) { values[j] = property.getInt64Values(j); } - mPropertyBundle.putLongArray(property.getName(), values); + mProperties.put(property.getName(), values); } else if (property.getDoubleValuesCount() > 0) { double[] values = new double[property.getDoubleValuesCount()]; for (int j = 0; j < values.length; j++) { values[j] = property.getDoubleValues(j); } - mPropertyBundle.putDoubleArray(property.getName(), values); + mProperties.put(property.getName(), values); } else if (property.getBooleanValuesCount() > 0) { boolean[] values = new boolean[property.getBooleanValuesCount()]; for (int j = 0; j < values.length; j++) { values[j] = property.getBooleanValues(j); } - mPropertyBundle.putBooleanArray(property.getName(), values); + mProperties.put(property.getName(), values); } else if (property.getBytesValuesCount() > 0) { byte[][] values = new byte[property.getBytesValuesCount()][]; for (int j = 0; j < values.length; j++) { values[j] = property.getBytesValues(j).toByteArray(); } - mPropertyBundle.putObject(name, values); + mProperties.put(name, values); } else if (property.getDocumentValuesCount() > 0) { AppSearchDocument[] values = new AppSearchDocument[property.getDocumentValuesCount()]; for (int j = 0; j < values.length; j++) { values[j] = new AppSearchDocument(property.getDocumentValues(j)); } - mPropertyBundle.putObject(name, values); + mProperties.put(name, values); } else { throw new IllegalStateException("Unknown type of value: " + name); } @@ -184,6 +185,19 @@ public class AppSearchDocument { } /** + * Returns the TTL (Time To Live) of the {@link AppSearchDocument}, in milliseconds. + * + * <p>The default value is 0, which means the document is permanent and won't be auto-deleted + * until the app is uninstalled. + * + * @hide + */ + @DurationMillisLong + public long getTtlMillis() { + return mProto.getTtlMs(); + } + + /** * Returns the score of the {@link AppSearchDocument}. * * <p>The score is a query-independent measure of the document's quality, relative to other @@ -202,7 +216,7 @@ public class AppSearchDocument { * * @param key The key to look for. * @return The first {@link String} associated with the given key or {@code null} if there - * is no such key or the value is of a different type. + * is no such key or the value is of a different type. * @hide */ @Nullable @@ -220,7 +234,7 @@ public class AppSearchDocument { * * @param key The key to look for. * @return The first {@link Long} associated with the given key or {@code null} if there - * is no such key or the value is of a different type. + * is no such key or the value is of a different type. * @hide */ @Nullable @@ -238,7 +252,7 @@ public class AppSearchDocument { * * @param key The key to look for. * @return The first {@link Double} associated with the given key or {@code null} if there - * is no such key or the value is of a different type. + * is no such key or the value is of a different type. * @hide */ @Nullable @@ -257,7 +271,7 @@ public class AppSearchDocument { * * @param key The key to look for. * @return The first {@link Boolean} associated with the given key or {@code null} if there - * is no such key or the value is of a different type. + * is no such key or the value is of a different type. * @hide */ @Nullable @@ -270,6 +284,23 @@ public class AppSearchDocument { return propertyArray[0]; } + /** + * Retrieve a {@code byte[]} value by key. + * + * @param key The key to look for. + * @return The first {@code byte[]} associated with the given key or {@code null} if there + * is no such key or the value is of a different type. + */ + @Nullable + public byte[] getPropertyBytes(@NonNull String key) { + byte[][] propertyArray = getPropertyBytesArray(key); + if (ArrayUtils.isEmpty(propertyArray)) { + return null; + } + warnIfSinglePropertyTooLong("ByteArray", key, propertyArray.length); + return propertyArray[0]; + } + /** Prints a warning to logcat if the given propertyLength is greater than 1. */ private static void warnIfSinglePropertyTooLong( @NonNull String propertyType, @NonNull String key, int propertyLength) { @@ -286,7 +317,7 @@ public class AppSearchDocument { * * @param key The key to look for. * @return The {@code String[]} associated with the given key, or {@code null} if no value - * is set or the value is of a different type. + * is set or the value is of a different type. * @hide */ @Nullable @@ -299,7 +330,7 @@ public class AppSearchDocument { * * @param key The key to look for. * @return The {@code long[]} associated with the given key, or {@code null} if no value is - * set or the value is of a different type. + * set or the value is of a different type. * @hide */ @Nullable @@ -312,7 +343,7 @@ public class AppSearchDocument { * * @param key The key to look for. * @return The {@code double[]} associated with the given key, or {@code null} if no value - * is set or the value is of a different type. + * is set or the value is of a different type. * @hide */ @Nullable @@ -325,7 +356,7 @@ public class AppSearchDocument { * * @param key The key to look for. * @return The {@code boolean[]} associated with the given key, or {@code null} if no value - * is set or the value is of a different type. + * is set or the value is of a different type. * @hide */ @Nullable @@ -334,12 +365,24 @@ public class AppSearchDocument { } /** + * Retrieve a {@code byte[][]} property by key. + * + * @param key The key to look for. + * @return The {@code byte[][]} associated with the given key, or {@code null} if no value + * is set or the value is of a different type. + */ + @Nullable + public byte[][] getPropertyBytesArray(@NonNull String key) { + return getAndCastPropertyArray(key, byte[][].class); + } + + /** * Gets a repeated property of the given key, and casts it to the given class type, which * must be an array class type. */ @Nullable private <T> T getAndCastPropertyArray(@NonNull String key, @NonNull Class<T> tClass) { - Object value = mPropertyBundle.get(key); + Object value = mProperties.get(key); if (value == null) { return null; } @@ -354,7 +397,7 @@ public class AppSearchDocument { @Override public boolean equals(@Nullable Object other) { // Check only proto's equality is sufficient here since all properties in - // mPropertyBundle are ordered by keys and stored in proto. + // mProperties are ordered by keys and stored in proto. if (this == other) { return true; } @@ -367,8 +410,8 @@ public class AppSearchDocument { @Override public int hashCode() { - // Hash only proto is sufficient here since all properties in mPropertyBundle are - // ordered by keys and stored in proto. + // Hash only proto is sufficient here since all properties in mProperties are ordered by + // keys and stored in proto. return mProto.hashCode(); } @@ -385,7 +428,7 @@ public class AppSearchDocument { */ public static class Builder<BuilderType extends Builder> { - private final Bundle mPropertyBundle = new Bundle(); + private final Map<String, Object> mProperties = new ArrayMap<>(); private final DocumentProto.Builder mProtoBuilder = DocumentProto.newBuilder(); private final BuilderType mBuilderTypeInstance; @@ -419,7 +462,7 @@ public class AppSearchDocument { @NonNull public BuilderType setScore(@IntRange(from = 0, to = Integer.MAX_VALUE) int score) { if (score < 0) { - throw new IllegalArgumentException("Document score cannot be negative"); + throw new IllegalArgumentException("Document score cannot be negative."); } mProtoBuilder.setScore(score); return mBuilderTypeInstance; @@ -439,6 +482,23 @@ public class AppSearchDocument { } /** + * Set the TTL (Time To Live) of the {@link AppSearchDocument}, in milliseconds. + * + * <p>After this many milliseconds since the {@link #setCreationTimestampMillis(long)} + * creation timestamp}, the document is deleted. + * + * @param ttlMillis A non-negative duration in milliseconds. + * @throws IllegalArgumentException If the provided value is negative. + */ + @NonNull + public BuilderType setTtlMillis(@DurationMillisLong long ttlMillis) { + Preconditions.checkArgumentNonNegative( + ttlMillis, "Document ttlMillis cannot be negative."); + mProtoBuilder.setTtlMs(ttlMillis); + return mBuilderTypeInstance; + } + + /** * Sets one or multiple {@code String} values for a property, replacing its previous * values. * @@ -448,7 +508,7 @@ public class AppSearchDocument { */ @NonNull public BuilderType setProperty(@NonNull String key, @NonNull String... values) { - putInBundle(mPropertyBundle, key, values); + putInPropertyMap(key, values); return mBuilderTypeInstance; } @@ -457,12 +517,11 @@ public class AppSearchDocument { * values. * * @param key The key associated with the {@code values}. - * @param values The {@code boolean} values of the schema.org property. - * @hide + * @param values The {@code boolean} values of the property. */ @NonNull public BuilderType setProperty(@NonNull String key, @NonNull boolean... values) { - putInBundle(mPropertyBundle, key, values); + putInPropertyMap(key, values); return mBuilderTypeInstance; } @@ -471,12 +530,11 @@ public class AppSearchDocument { * values. * * @param key The key associated with the {@code values}. - * @param values The {@code long} values of the schema.org property. - * @hide + * @param values The {@code long} values of the property. */ @NonNull public BuilderType setProperty(@NonNull String key, @NonNull long... values) { - putInBundle(mPropertyBundle, key, values); + putInPropertyMap(key, values); return mBuilderTypeInstance; } @@ -485,17 +543,27 @@ public class AppSearchDocument { * values. * * @param key The key associated with the {@code values}. - * @param values The {@code double} values of the schema.org property. - * @hide + * @param values The {@code double} values of the property. */ @NonNull public BuilderType setProperty(@NonNull String key, @NonNull double... values) { - putInBundle(mPropertyBundle, key, values); + putInPropertyMap(key, values); + return mBuilderTypeInstance; + } + + /** + * Sets one or multiple {@code byte[]} for a property, replacing its previous values. + * + * @param key The key associated with the {@code values}. + * @param values The {@code byte[]} of the property. + */ + @NonNull + public BuilderType setProperty(@NonNull String key, @NonNull byte[]... values) { + putInPropertyMap(key, values); return mBuilderTypeInstance; } - private static void putInBundle( - @NonNull Bundle bundle, @NonNull String key, @NonNull String... values) + private void putInPropertyMap(@NonNull String key, @NonNull String[] values) throws IllegalArgumentException { Objects.requireNonNull(key); Objects.requireNonNull(values); @@ -509,33 +577,38 @@ public class AppSearchDocument { + MAX_STRING_LENGTH + "."); } } - bundle.putStringArray(key, values); + mProperties.put(key, values); } - private static void putInBundle( - @NonNull Bundle bundle, @NonNull String key, @NonNull boolean... values) { + private void putInPropertyMap(@NonNull String key, @NonNull boolean[] values) { Objects.requireNonNull(key); Objects.requireNonNull(values); validateRepeatedPropertyLength(key, values.length); - bundle.putBooleanArray(key, values); + mProperties.put(key, values); } - private static void putInBundle( - @NonNull Bundle bundle, @NonNull String key, @NonNull double... values) { + private void putInPropertyMap(@NonNull String key, @NonNull double[] values) { Objects.requireNonNull(key); Objects.requireNonNull(values); validateRepeatedPropertyLength(key, values.length); - bundle.putDoubleArray(key, values); + mProperties.put(key, values); } - private static void putInBundle( - @NonNull Bundle bundle, @NonNull String key, @NonNull long... values) { + private void putInPropertyMap(@NonNull String key, @NonNull long[] values) { Objects.requireNonNull(key); Objects.requireNonNull(values); validateRepeatedPropertyLength(key, values.length); - bundle.putLongArray(key, values); + mProperties.put(key, values); } + private void putInPropertyMap(@NonNull String key, @NonNull byte[][] values) { + Objects.requireNonNull(key); + Objects.requireNonNull(values); + validateRepeatedPropertyLength(key, values.length); + mProperties.put(key, values); + } + + private static void validateRepeatedPropertyLength(@NonNull String key, int length) { if (length == 0) { throw new IllegalArgumentException("The input array is empty."); @@ -552,14 +625,15 @@ public class AppSearchDocument { * @hide */ public AppSearchDocument build() { - // Build proto by sorting the keys in propertyBundle to exclude the influence of + // Build proto by sorting the keys in mProperties to exclude the influence of // order. Therefore documents will generate same proto as long as the contents are // same. Note that the order of repeated fields is still preserved. - ArrayList<String> keys = new ArrayList<>(mPropertyBundle.keySet()); + ArrayList<String> keys = new ArrayList<>(mProperties.keySet()); Collections.sort(keys); - for (String key : keys) { - Object values = mPropertyBundle.get(key); - PropertyProto.Builder propertyProto = PropertyProto.newBuilder().setName(key); + for (int i = 0; i < keys.size(); i++) { + String name = keys.get(i); + Object values = mProperties.get(name); + PropertyProto.Builder propertyProto = PropertyProto.newBuilder().setName(name); if (values instanceof boolean[]) { for (boolean value : (boolean[]) values) { propertyProto.addBooleanValues(value); @@ -576,14 +650,18 @@ public class AppSearchDocument { for (String value : (String[]) values) { propertyProto.addStringValues(value); } + } else if (values instanceof byte[][]) { + for (byte[] value : (byte[][]) values) { + propertyProto.addBytesValues(ByteString.copyFrom(value)); + } } else { throw new IllegalStateException( - "Property \"" + key + "\" has unsupported value type \"" + "Property \"" + name + "\" has unsupported value type \"" + values.getClass().getSimpleName() + "\""); } mProtoBuilder.addProperties(propertyProto); } - return new AppSearchDocument(mProtoBuilder.build(), mPropertyBundle); + return new AppSearchDocument(mProtoBuilder.build(), mProperties); } } } diff --git a/core/tests/coretests/src/android/app/appsearch/AppSearchDocumentTest.java b/core/tests/coretests/src/android/app/appsearch/AppSearchDocumentTest.java index 7b07201479ef..f2911717c915 100644 --- a/core/tests/coretests/src/android/app/appsearch/AppSearchDocumentTest.java +++ b/core/tests/coretests/src/android/app/appsearch/AppSearchDocumentTest.java @@ -24,6 +24,7 @@ import androidx.test.filters.SmallTest; import com.google.android.icing.proto.DocumentProto; import com.google.android.icing.proto.PropertyProto; +import com.google.android.icing.protobuf.ByteString; import org.junit.Test; @@ -34,22 +35,28 @@ import java.util.List; @SmallTest public class AppSearchDocumentTest { + private static final byte[] sByteArray1 = new byte[]{(byte) 1, (byte) 2, (byte) 3}; + private static final byte[] sByteArray2 = new byte[]{(byte) 4, (byte) 5, (byte) 6}; @Test public void testDocumentEquals_Identical() { AppSearchDocument document1 = new AppSearchDocument.Builder("uri1", "schemaType1") .setCreationTimestampMillis(5L) + .setTtlMillis(1L) .setProperty("longKey1", 1L, 2L, 3L) .setProperty("doubleKey1", 1.0, 2.0, 3.0) .setProperty("booleanKey1", true, false, true) .setProperty("stringKey1", "test-value1", "test-value2", "test-value3") + .setProperty("byteKey1", sByteArray1, sByteArray2) .build(); AppSearchDocument document2 = new AppSearchDocument.Builder("uri1", "schemaType1") .setCreationTimestampMillis(5L) + .setTtlMillis(1L) .setProperty("longKey1", 1L, 2L, 3L) .setProperty("doubleKey1", 1.0, 2.0, 3.0) .setProperty("booleanKey1", true, false, true) .setProperty("stringKey1", "test-value1", "test-value2", "test-value3") + .setProperty("byteKey1", sByteArray1, sByteArray2) .build(); assertThat(document1).isEqualTo(document2); assertThat(document1.hashCode()).isEqualTo(document2.hashCode()); @@ -60,6 +67,7 @@ public class AppSearchDocumentTest { AppSearchDocument document1 = new AppSearchDocument.Builder("uri1", "schemaType1") .setCreationTimestampMillis(5L) .setProperty("longKey1", 1L, 2L, 3L) + .setProperty("byteKey1", sByteArray1, sByteArray2) .setProperty("doubleKey1", 1.0, 2.0, 3.0) .setProperty("booleanKey1", true, false, true) .setProperty("stringKey1", "test-value1", "test-value2", "test-value3") @@ -71,6 +79,7 @@ public class AppSearchDocumentTest { .setProperty("booleanKey1", true, false, true) .setProperty("stringKey1", "test-value1", "test-value2", "test-value3") .setProperty("doubleKey1", 1.0, 2.0, 3.0) + .setProperty("byteKey1", sByteArray1, sByteArray2) .setProperty("longKey1", 1L, 2L, 3L) .build(); assertThat(document1).isEqualTo(document2); @@ -114,11 +123,14 @@ public class AppSearchDocumentTest { AppSearchDocument document = new AppSearchDocument.Builder("uri1", "schemaType1") .setCreationTimestampMillis(5L) .setScore(1) + .setTtlMillis(1L) .setProperty("longKey1", 1L) .setProperty("doubleKey1", 1.0) .setProperty("booleanKey1", true) - .setProperty("stringKey1", "test-value1").build(); + .setProperty("stringKey1", "test-value1") + .setProperty("byteKey1", sByteArray1).build(); assertThat(document.getUri()).isEqualTo("uri1"); + assertThat(document.getTtlMillis()).isEqualTo(1L); assertThat(document.getSchemaType()).isEqualTo("schemaType1"); assertThat(document.getCreationTimestampMillis()).isEqualTo(5); assertThat(document.getScore()).isEqualTo(1); @@ -126,6 +138,8 @@ public class AppSearchDocumentTest { assertThat(document.getPropertyDouble("doubleKey1")).isEqualTo(1.0); assertThat(document.getPropertyBoolean("booleanKey1")).isTrue(); assertThat(document.getPropertyString("stringKey1")).isEqualTo("test-value1"); + assertThat(document.getPropertyBytes("byteKey1")) + .asList().containsExactly((byte) 1, (byte) 2, (byte) 3); } @Test @@ -136,6 +150,7 @@ public class AppSearchDocumentTest { .setProperty("doubleKey1", 1.0, 2.0, 3.0) .setProperty("booleanKey1", true, false, true) .setProperty("stringKey1", "test-value1", "test-value2", "test-value3") + .setProperty("byteKey1", sByteArray1, sByteArray2) .build(); assertThat(document.getUri()).isEqualTo("uri1"); @@ -147,6 +162,8 @@ public class AppSearchDocumentTest { .containsExactly(true, false, true); assertThat(document.getPropertyStringArray("stringKey1")).asList() .containsExactly("test-value1", "test-value2", "test-value3"); + assertThat(document.getPropertyBytesArray("byteKey1")).asList() + .containsExactly(sByteArray1, sByteArray2); } @Test @@ -188,15 +205,21 @@ public class AppSearchDocumentTest { AppSearchDocument document = new AppSearchDocument.Builder("uri1", "schemaType1") .setCreationTimestampMillis(5L) .setScore(1) + .setTtlMillis(1L) .setProperty("longKey1", 1L) .setProperty("doubleKey1", 1.0) .setProperty("booleanKey1", true) .setProperty("stringKey1", "test-value1") + .setProperty("byteKey1", sByteArray1) .build(); // Create the Document proto. Need to sort the property order by key. DocumentProto.Builder documentProtoBuilder = DocumentProto.newBuilder() - .setUri("uri1").setSchema("schemaType1").setScore(1).setCreationTimestampMs(5L); + .setUri("uri1") + .setSchema("schemaType1") + .setCreationTimestampMs(5L) + .setScore(1) + .setTtlMs(1L); HashMap<String, PropertyProto.Builder> propertyProtoMap = new HashMap<>(); propertyProtoMap.put("longKey1", PropertyProto.newBuilder().setName("longKey1").addInt64Values(1L)); @@ -206,6 +229,9 @@ public class AppSearchDocumentTest { PropertyProto.newBuilder().setName("booleanKey1").addBooleanValues(true)); propertyProtoMap.put("stringKey1", PropertyProto.newBuilder().setName("stringKey1").addStringValues("test-value1")); + propertyProtoMap.put("byteKey1", + PropertyProto.newBuilder().setName("byteKey1").addBytesValues( + ByteString.copyFrom(sByteArray1))); List<String> sortedKey = new ArrayList<>(propertyProtoMap.keySet()); Collections.sort(sortedKey); for (String key : sortedKey) { diff --git a/core/tests/coretests/src/android/app/appsearch/impl/CustomerDocumentTest.java b/core/tests/coretests/src/android/app/appsearch/impl/CustomerDocumentTest.java index 294031782b67..24d8b44ace5f 100644 --- a/core/tests/coretests/src/android/app/appsearch/impl/CustomerDocumentTest.java +++ b/core/tests/coretests/src/android/app/appsearch/impl/CustomerDocumentTest.java @@ -34,6 +34,10 @@ import org.junit.Test; */ @SmallTest public class CustomerDocumentTest { + + private static byte[] sByteArray1 = new byte[]{(byte) 1, (byte) 2, (byte) 3}; + private static byte[] sByteArray2 = new byte[]{(byte) 4, (byte) 5, (byte) 6}; + @Test public void testBuildCustomerDocument() { CustomerDocument customerDocument = new CustomerDocument.Builder("uri1") @@ -43,6 +47,7 @@ public class CustomerDocumentTest { .setProperty("doubleKey1", 1.0, 2.0, 3.0) .setProperty("booleanKey1", true, false, true) .setProperty("stringKey1", "test-value1", "test-value2", "test-value3") + .setProperty("byteKey1", sByteArray1, sByteArray2) .build(); assertThat(customerDocument.getUri()).isEqualTo("uri1"); @@ -57,6 +62,8 @@ public class CustomerDocumentTest { .containsExactly(true, false, true); assertThat(customerDocument.getPropertyStringArray("stringKey1")).asList() .containsExactly("test-value1", "test-value2", "test-value3"); + assertThat(customerDocument.getPropertyBytesArray("byteKey1")).asList() + .containsExactly(sByteArray1, sByteArray2); } /** |