blob: 6dd915887839cca62c601ba97d51a9c87cdf9722 [file] [log] [blame]
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.appsearch.cts.app;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import android.app.appsearch.AppSearchSchema;
import android.app.appsearch.AppSearchSchema.PropertyConfig;
import android.app.appsearch.AppSearchSchema.StringPropertyConfig;
import com.android.server.appsearch.testing.AppSearchEmail;
import org.junit.Test;
import java.util.List;
public class AppSearchSchemaCtsTest {
@Test
public void testInvalidEnums() {
StringPropertyConfig.Builder builder = new StringPropertyConfig.Builder("test");
assertThrows(IllegalArgumentException.class, () -> builder.setCardinality(99));
}
@Test
public void testDefaultValues() {
StringPropertyConfig builder = new StringPropertyConfig.Builder("test").build();
assertThat(builder.getIndexingType()).isEqualTo(StringPropertyConfig.INDEXING_TYPE_NONE);
assertThat(builder.getTokenizerType()).isEqualTo(StringPropertyConfig.TOKENIZER_TYPE_NONE);
assertThat(builder.getCardinality()).isEqualTo(PropertyConfig.CARDINALITY_OPTIONAL);
}
@Test
public void testDuplicateProperties() {
AppSearchSchema.Builder builder =
new AppSearchSchema.Builder("Email")
.addProperty(
new StringPropertyConfig.Builder("subject")
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
.setIndexingType(
StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.build());
IllegalArgumentException e =
assertThrows(
IllegalArgumentException.class,
() ->
builder.addProperty(
new StringPropertyConfig.Builder("subject")
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
.setIndexingType(
StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.setTokenizerType(
StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.build()));
assertThat(e).hasMessageThat().contains("Property defined more than once: subject");
}
@Test
public void testEquals_identical() {
AppSearchSchema schema1 =
new AppSearchSchema.Builder("Email")
.addProperty(
new StringPropertyConfig.Builder("subject")
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
.setIndexingType(
StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.build())
.build();
AppSearchSchema schema2 =
new AppSearchSchema.Builder("Email")
.addProperty(
new StringPropertyConfig.Builder("subject")
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
.setIndexingType(
StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.build())
.build();
assertThat(schema1).isEqualTo(schema2);
assertThat(schema1.hashCode()).isEqualTo(schema2.hashCode());
}
@Test
public void testEquals_differentOrder() {
AppSearchSchema schema1 =
new AppSearchSchema.Builder("Email")
.addProperty(
new StringPropertyConfig.Builder("subject")
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
.setIndexingType(
StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.build())
.build();
AppSearchSchema schema2 =
new AppSearchSchema.Builder("Email")
.addProperty(
new StringPropertyConfig.Builder("subject")
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.setIndexingType(
StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
.build())
.build();
assertThat(schema1).isEqualTo(schema2);
assertThat(schema1.hashCode()).isEqualTo(schema2.hashCode());
}
@Test
public void testEquals_failure_differentProperty() {
AppSearchSchema schema1 =
new AppSearchSchema.Builder("Email")
.addProperty(
new StringPropertyConfig.Builder("subject")
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
.setIndexingType(
StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.build())
.build();
AppSearchSchema schema2 =
new AppSearchSchema.Builder("Email")
.addProperty(
new StringPropertyConfig.Builder("subject")
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
.setIndexingType(
StringPropertyConfig
.INDEXING_TYPE_EXACT_TERMS) // Diff
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.build())
.build();
assertThat(schema1).isNotEqualTo(schema2);
assertThat(schema1.hashCode()).isNotEqualTo(schema2.hashCode());
}
@Test
public void testEquals_failure_differentOrder() {
AppSearchSchema schema1 =
new AppSearchSchema.Builder("Email")
.addProperty(
new StringPropertyConfig.Builder("subject")
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
.setIndexingType(
StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.build())
.addProperty(
new StringPropertyConfig.Builder("body")
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
.setIndexingType(
StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.build())
.build();
// Order of 'body' and 'subject' has been switched
AppSearchSchema schema2 =
new AppSearchSchema.Builder("Email")
.addProperty(
new StringPropertyConfig.Builder("body")
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
.setIndexingType(
StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.build())
.addProperty(
new StringPropertyConfig.Builder("subject")
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
.setIndexingType(
StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.build())
.build();
assertThat(schema1).isNotEqualTo(schema2);
assertThat(schema1.hashCode()).isNotEqualTo(schema2.hashCode());
}
@Test
public void testPropertyConfig() {
AppSearchSchema schema =
new AppSearchSchema.Builder("Test")
.addProperty(
new StringPropertyConfig.Builder("string")
.setCardinality(PropertyConfig.CARDINALITY_REQUIRED)
.setIndexingType(
StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.build())
.addProperty(
new AppSearchSchema.LongPropertyConfig.Builder("long")
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
.build())
.addProperty(
new AppSearchSchema.DoublePropertyConfig.Builder("double")
.setCardinality(PropertyConfig.CARDINALITY_REPEATED)
.build())
.addProperty(
new AppSearchSchema.BooleanPropertyConfig.Builder("boolean")
.setCardinality(PropertyConfig.CARDINALITY_REQUIRED)
.build())
.addProperty(
new AppSearchSchema.BytesPropertyConfig.Builder("bytes")
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
.build())
.addProperty(
new AppSearchSchema.DocumentPropertyConfig.Builder(
"document", AppSearchEmail.SCHEMA_TYPE)
.setCardinality(PropertyConfig.CARDINALITY_REPEATED)
.setShouldIndexNestedProperties(true)
.build())
.build();
assertThat(schema.getSchemaType()).isEqualTo("Test");
List<PropertyConfig> properties = schema.getProperties();
assertThat(properties).hasSize(6);
assertThat(properties.get(0).getName()).isEqualTo("string");
assertThat(properties.get(0).getCardinality())
.isEqualTo(PropertyConfig.CARDINALITY_REQUIRED);
assertThat(((StringPropertyConfig) properties.get(0)).getIndexingType())
.isEqualTo(StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS);
assertThat(((StringPropertyConfig) properties.get(0)).getTokenizerType())
.isEqualTo(StringPropertyConfig.TOKENIZER_TYPE_PLAIN);
assertThat(properties.get(1).getName()).isEqualTo("long");
assertThat(properties.get(1).getCardinality())
.isEqualTo(PropertyConfig.CARDINALITY_OPTIONAL);
assertThat(properties.get(1)).isInstanceOf(AppSearchSchema.LongPropertyConfig.class);
assertThat(properties.get(2).getName()).isEqualTo("double");
assertThat(properties.get(2).getCardinality())
.isEqualTo(PropertyConfig.CARDINALITY_REPEATED);
assertThat(properties.get(2)).isInstanceOf(AppSearchSchema.DoublePropertyConfig.class);
assertThat(properties.get(3).getName()).isEqualTo("boolean");
assertThat(properties.get(3).getCardinality())
.isEqualTo(PropertyConfig.CARDINALITY_REQUIRED);
assertThat(properties.get(3)).isInstanceOf(AppSearchSchema.BooleanPropertyConfig.class);
assertThat(properties.get(4).getName()).isEqualTo("bytes");
assertThat(properties.get(4).getCardinality())
.isEqualTo(PropertyConfig.CARDINALITY_OPTIONAL);
assertThat(properties.get(4)).isInstanceOf(AppSearchSchema.BytesPropertyConfig.class);
assertThat(properties.get(5).getName()).isEqualTo("document");
assertThat(properties.get(5).getCardinality())
.isEqualTo(PropertyConfig.CARDINALITY_REPEATED);
assertThat(((AppSearchSchema.DocumentPropertyConfig) properties.get(5)).getSchemaType())
.isEqualTo(AppSearchEmail.SCHEMA_TYPE);
assertThat(
((AppSearchSchema.DocumentPropertyConfig) properties.get(5))
.shouldIndexNestedProperties())
.isEqualTo(true);
}
@Test
public void testInvalidStringPropertyConfigsTokenizerNone() {
// Everything should work fine with the defaults.
final StringPropertyConfig.Builder builder = new StringPropertyConfig.Builder("property");
assertThat(builder.build()).isNotNull();
// Setting an indexing type other NONE with the default tokenizer type (NONE) should fail.
builder.setIndexingType(StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS);
assertThrows(IllegalStateException.class, () -> builder.build());
builder.setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES);
assertThrows(IllegalStateException.class, () -> builder.build());
// Explicitly setting the default should work fine.
builder.setIndexingType(StringPropertyConfig.INDEXING_TYPE_NONE);
assertThat(builder.build()).isNotNull();
// Explicitly setting the default tokenizer type should result in the same behavior.
builder.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_NONE)
.setIndexingType(StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS);
assertThrows(IllegalStateException.class, () -> builder.build());
builder.setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES);
assertThrows(IllegalStateException.class, () -> builder.build());
builder.setIndexingType(StringPropertyConfig.INDEXING_TYPE_NONE);
assertThat(builder.build()).isNotNull();
}
@Test
public void testInvalidStringPropertyConfigsTokenizerPlain() {
// Setting indexing type to be NONE with tokenizer type PLAIN should fail. Regardless of
// whether NONE is set explicitly or just kept as default.
final StringPropertyConfig.Builder builder =
new StringPropertyConfig.Builder("property")
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN);
assertThrows(IllegalStateException.class, () -> builder.build());
builder.setIndexingType(StringPropertyConfig.INDEXING_TYPE_NONE);
assertThrows(IllegalStateException.class, () -> builder.build());
// Setting indexing type to be something other than NONE with tokenizer type PLAIN should
// be just fine.
builder.setIndexingType(StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS);
assertThat(builder.build()).isNotNull();
builder.setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES);
assertThat(builder.build()).isNotNull();
}
@Test
public void testAppSearchSchema_toString() {
AppSearchSchema schema =
new AppSearchSchema.Builder("testSchema")
.addProperty(
new StringPropertyConfig.Builder("string1")
.setCardinality(PropertyConfig.CARDINALITY_REQUIRED)
.setIndexingType(StringPropertyConfig.INDEXING_TYPE_NONE)
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_NONE)
.build())
.addProperty(
new StringPropertyConfig.Builder("string2")
.setCardinality(PropertyConfig.CARDINALITY_REQUIRED)
.setIndexingType(
StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.build())
.addProperty(
new StringPropertyConfig.Builder("string3")
.setCardinality(PropertyConfig.CARDINALITY_REQUIRED)
.setIndexingType(
StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.build())
.addProperty(
new AppSearchSchema.LongPropertyConfig.Builder("long")
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
.build())
.addProperty(
new AppSearchSchema.DoublePropertyConfig.Builder("double")
.setCardinality(PropertyConfig.CARDINALITY_REPEATED)
.build())
.addProperty(
new AppSearchSchema.BooleanPropertyConfig.Builder("boolean")
.setCardinality(PropertyConfig.CARDINALITY_REQUIRED)
.build())
.addProperty(
new AppSearchSchema.BytesPropertyConfig.Builder("bytes")
.setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
.build())
.addProperty(
new AppSearchSchema.DocumentPropertyConfig.Builder(
"document", AppSearchEmail.SCHEMA_TYPE)
.setCardinality(PropertyConfig.CARDINALITY_REPEATED)
.setShouldIndexNestedProperties(true)
.build())
.build();
String schemaString = schema.toString();
String expectedString =
"{\n"
+ " schemaType: \"testSchema\",\n"
+ " properties: [\n"
+ " {\n"
+ " name: \"boolean\",\n"
+ " cardinality: CARDINALITY_REQUIRED,\n"
+ " dataType: DATA_TYPE_BOOLEAN,\n"
+ " },\n"
+ " {\n"
+ " name: \"bytes\",\n"
+ " cardinality: CARDINALITY_OPTIONAL,\n"
+ " dataType: DATA_TYPE_BYTES,\n"
+ " },\n"
+ " {\n"
+ " name: \"document\",\n"
+ " shouldIndexNestedProperties: true,\n"
+ " schemaType: \"builtin:Email\",\n"
+ " cardinality: CARDINALITY_REPEATED,\n"
+ " dataType: DATA_TYPE_DOCUMENT,\n"
+ " },\n"
+ " {\n"
+ " name: \"double\",\n"
+ " cardinality: CARDINALITY_REPEATED,\n"
+ " dataType: DATA_TYPE_DOUBLE,\n"
+ " },\n"
+ " {\n"
+ " name: \"long\",\n"
+ " cardinality: CARDINALITY_OPTIONAL,\n"
+ " dataType: DATA_TYPE_LONG,\n"
+ " },\n"
+ " {\n"
+ " name: \"string1\",\n"
+ " indexingType: INDEXING_TYPE_NONE,\n"
+ " tokenizerType: TOKENIZER_TYPE_NONE,\n"
+ " cardinality: CARDINALITY_REQUIRED,\n"
+ " dataType: DATA_TYPE_STRING,\n"
+ " },\n"
+ " {\n"
+ " name: \"string2\",\n"
+ " indexingType: INDEXING_TYPE_EXACT_TERMS,\n"
+ " tokenizerType: TOKENIZER_TYPE_PLAIN,\n"
+ " cardinality: CARDINALITY_REQUIRED,\n"
+ " dataType: DATA_TYPE_STRING,\n"
+ " },\n"
+ " {\n"
+ " name: \"string3\",\n"
+ " indexingType: INDEXING_TYPE_PREFIXES,\n"
+ " tokenizerType: TOKENIZER_TYPE_PLAIN,\n"
+ " cardinality: CARDINALITY_REQUIRED,\n"
+ " dataType: DATA_TYPE_STRING,\n"
+ " }\n"
+ " ]\n"
+ "}";
assertThat(schemaString).isEqualTo(expectedString);
}
}