1 // Copyright (C) 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "icing/schema/joinable-property-manager.h"
16
17 #include <cstdint>
18 #include <memory>
19 #include <string>
20 #include <string_view>
21 #include <vector>
22
23 #include "icing/text_classifier/lib3/utils/base/status.h"
24 #include "gmock/gmock.h"
25 #include "gtest/gtest.h"
26 #include "icing/document-builder.h"
27 #include "icing/file/filesystem.h"
28 #include "icing/proto/document.pb.h"
29 #include "icing/proto/schema.pb.h"
30 #include "icing/schema-builder.h"
31 #include "icing/schema/joinable-property.h"
32 #include "icing/schema/schema-type-manager.h"
33 #include "icing/schema/schema-util.h"
34 #include "icing/store/dynamic-trie-key-mapper.h"
35 #include "icing/store/key-mapper.h"
36 #include "icing/testing/common-matchers.h"
37 #include "icing/testing/tmp-directory.h"
38
39 namespace icing {
40 namespace lib {
41
42 namespace {
43
44 using ::testing::ElementsAre;
45 using ::testing::IsNull;
46 using ::testing::Pointee;
47 using ::testing::SizeIs;
48
49 // type and property names of Email
50 static constexpr char kTypeEmail[] = "Email";
51 // joinable
52 static constexpr char kPropertyReceiverQualifiedId[] = "receiverQualifiedId";
53 static constexpr char kPropertySenderQualifiedId[] = "senderQualifiedId";
54 // non-joinable
55 static constexpr char kPropertyAttachment[] = "attachment";
56 static constexpr char kPropertySubject[] = "subject";
57 static constexpr char kPropertyText[] = "text";
58 static constexpr char kPropertyTimestamp[] = "timestamp";
59
60 // type and property names of Conversation
61 static constexpr char kTypeConversation[] = "Conversation";
62 // joinable
63 static constexpr char kPropertyEmails[] = "emails";
64 static constexpr char kPropertyGroupQualifiedId[] = "groupQualifiedId";
65 // non-joinable
66 static constexpr char kPropertyName[] = "name";
67 static constexpr char kPropertyNumber[] = "number";
68
69 constexpr int64_t kDefaultTimestamp = 1663274901;
70
CreateSenderQualifiedIdPropertyConfig()71 PropertyConfigProto CreateSenderQualifiedIdPropertyConfig() {
72 return PropertyConfigBuilder()
73 .SetName(kPropertySenderQualifiedId)
74 .SetDataTypeString(TERM_MATCH_PREFIX, TOKENIZER_PLAIN)
75 .SetJoinable(JOINABLE_VALUE_TYPE_QUALIFIED_ID, /*propagate_delete=*/true)
76 .SetCardinality(CARDINALITY_OPTIONAL)
77 .Build();
78 }
79
CreateReceiverQualifiedIdPropertyConfig()80 PropertyConfigProto CreateReceiverQualifiedIdPropertyConfig() {
81 return PropertyConfigBuilder()
82 .SetName(kPropertyReceiverQualifiedId)
83 .SetDataTypeString(TERM_MATCH_PREFIX, TOKENIZER_PLAIN)
84 .SetJoinable(JOINABLE_VALUE_TYPE_QUALIFIED_ID, /*propagate_delete=*/true)
85 .SetCardinality(CARDINALITY_OPTIONAL)
86 .Build();
87 }
88
CreateGroupQualifiedIdPropertyConfig()89 PropertyConfigProto CreateGroupQualifiedIdPropertyConfig() {
90 return PropertyConfigBuilder()
91 .SetName(kPropertyGroupQualifiedId)
92 .SetDataTypeString(TERM_MATCH_PREFIX, TOKENIZER_PLAIN)
93 .SetJoinable(JOINABLE_VALUE_TYPE_QUALIFIED_ID, /*propagate_delete=*/false)
94 .SetCardinality(CARDINALITY_OPTIONAL)
95 .Build();
96 }
97
CreateEmailTypeConfig()98 SchemaTypeConfigProto CreateEmailTypeConfig() {
99 return SchemaTypeConfigBuilder()
100 .SetType(kTypeEmail)
101 .AddProperty(PropertyConfigBuilder()
102 .SetName(kPropertySubject)
103 .SetDataTypeString(TERM_MATCH_EXACT, TOKENIZER_PLAIN)
104 .SetCardinality(CARDINALITY_OPTIONAL))
105 .AddProperty(PropertyConfigBuilder()
106 .SetName(kPropertyText)
107 .SetDataTypeString(TERM_MATCH_UNKNOWN, TOKENIZER_NONE)
108 .SetCardinality(CARDINALITY_OPTIONAL))
109 .AddProperty(PropertyConfigBuilder()
110 .SetName(kPropertyAttachment)
111 .SetDataType(TYPE_BYTES)
112 .SetCardinality(CARDINALITY_OPTIONAL))
113 .AddProperty(PropertyConfigBuilder()
114 .SetName(kPropertyTimestamp)
115 .SetDataType(TYPE_INT64)
116 .SetCardinality(CARDINALITY_OPTIONAL))
117 .AddProperty(CreateSenderQualifiedIdPropertyConfig())
118 .AddProperty(CreateReceiverQualifiedIdPropertyConfig())
119 .Build();
120 }
121
CreateConversationTypeConfig()122 SchemaTypeConfigProto CreateConversationTypeConfig() {
123 return SchemaTypeConfigBuilder()
124 .SetType(kTypeConversation)
125 .AddProperty(PropertyConfigBuilder()
126 .SetName(kPropertyName)
127 .SetDataTypeString(TERM_MATCH_EXACT, TOKENIZER_PLAIN)
128 .SetCardinality(CARDINALITY_OPTIONAL))
129 .AddProperty(PropertyConfigBuilder()
130 .SetName(kPropertyNumber)
131 .SetDataType(TYPE_INT64)
132 .SetCardinality(CARDINALITY_OPTIONAL))
133 .AddProperty(CreateGroupQualifiedIdPropertyConfig())
134 .AddProperty(
135 PropertyConfigBuilder()
136 .SetName(kPropertyEmails)
137 .SetDataTypeDocument(kTypeEmail, /*index_nested_properties=*/true)
138 .SetCardinality(CARDINALITY_OPTIONAL))
139 .Build();
140 }
141
142 class JoinablePropertyManagerTest : public ::testing::Test {
143 protected:
SetUp()144 void SetUp() override {
145 test_dir_ = GetTestTempDir() + "/icing";
146
147 type_config_map_.emplace(kTypeEmail, CreateEmailTypeConfig());
148 type_config_map_.emplace(kTypeConversation, CreateConversationTypeConfig());
149
150 email_document_ =
151 DocumentBuilder()
152 .SetKey("icing", "email/1")
153 .SetSchema(kTypeEmail)
154 .AddStringProperty(kPropertySubject, "the subject")
155 .AddStringProperty(kPropertyText, "the text")
156 .AddStringProperty(kPropertySenderQualifiedId, "pkg$db/ns#Person1")
157 .AddStringProperty(kPropertyReceiverQualifiedId,
158 "pkg$db/ns#Person2")
159 .AddBytesProperty(kPropertyAttachment, "attachment")
160 .AddInt64Property(kPropertyTimestamp, kDefaultTimestamp)
161 .Build();
162
163 conversation_document_ =
164 DocumentBuilder()
165 .SetKey("icing", "conversation/1")
166 .SetSchema(kTypeConversation)
167 .AddStringProperty(kPropertyName, "the conversation")
168 .AddInt64Property(kPropertyNumber, 2)
169 .AddDocumentProperty(kPropertyEmails,
170 DocumentProto(email_document_))
171 .AddStringProperty(kPropertyGroupQualifiedId,
172 "pkg$db/ns#GroupQualifiedId1")
173 .Build();
174
175 // DynamicTrieKeyMapper uses 3 internal arrays for bookkeeping. Give each
176 // one 128KiB so the total DynamicTrieKeyMapper should get 384KiB
177 int key_mapper_size = 3 * 128 * 1024;
178 ICING_ASSERT_OK_AND_ASSIGN(schema_type_mapper_,
179 DynamicTrieKeyMapper<SchemaTypeId>::Create(
180 filesystem_, test_dir_, key_mapper_size));
181 ICING_ASSERT_OK(schema_type_mapper_->Put(kTypeEmail, 0));
182 ICING_ASSERT_OK(schema_type_mapper_->Put(kTypeConversation, 1));
183 }
184
TearDown()185 void TearDown() override {
186 schema_type_mapper_.reset();
187 filesystem_.DeleteDirectoryRecursively(test_dir_.c_str());
188 }
189
190 Filesystem filesystem_;
191 std::string test_dir_;
192 SchemaUtil::TypeConfigMap type_config_map_;
193 std::unique_ptr<KeyMapper<SchemaTypeId>> schema_type_mapper_;
194
195 DocumentProto email_document_;
196 DocumentProto conversation_document_;
197 };
198
TEST_F(JoinablePropertyManagerTest,ExtractJoinableProperties)199 TEST_F(JoinablePropertyManagerTest, ExtractJoinableProperties) {
200 // Use SchemaTypeManager factory method to instantiate
201 // JoinablePropertyManager.
202 ICING_ASSERT_OK_AND_ASSIGN(
203 std::unique_ptr<SchemaTypeManager> schema_type_manager,
204 SchemaTypeManager::Create(type_config_map_, schema_type_mapper_.get()));
205
206 // Extracts all joinable properties from 'Email' document
207 ICING_ASSERT_OK_AND_ASSIGN(JoinablePropertyGroup joinable_property_group,
208 schema_type_manager->joinable_property_manager()
209 .ExtractJoinableProperties(email_document_));
210
211 // Qualified Id joinable properties
212 EXPECT_THAT(joinable_property_group.qualified_id_properties, SizeIs(2));
213
214 EXPECT_THAT(
215 joinable_property_group.qualified_id_properties[0].metadata,
216 EqualsJoinablePropertyMetadata(
217 /*expected_id=*/0, /*expected_property_path=*/"receiverQualifiedId",
218 CreateReceiverQualifiedIdPropertyConfig()));
219 EXPECT_THAT(joinable_property_group.qualified_id_properties[0].values,
220 ElementsAre("pkg$db/ns#Person2"));
221
222 EXPECT_THAT(
223 joinable_property_group.qualified_id_properties[1].metadata,
224 EqualsJoinablePropertyMetadata(
225 /*expected_id=*/1, /*expected_property_path=*/"senderQualifiedId",
226 CreateSenderQualifiedIdPropertyConfig()));
227 EXPECT_THAT(joinable_property_group.qualified_id_properties[1].values,
228 ElementsAre("pkg$db/ns#Person1"));
229 }
230
TEST_F(JoinablePropertyManagerTest,ExtractJoinablePropertiesNested)231 TEST_F(JoinablePropertyManagerTest, ExtractJoinablePropertiesNested) {
232 // Use SchemaTypeManager factory method to instantiate
233 // JoinablePropertyManager.
234 ICING_ASSERT_OK_AND_ASSIGN(
235 std::unique_ptr<SchemaTypeManager> schema_type_manager,
236 SchemaTypeManager::Create(type_config_map_, schema_type_mapper_.get()));
237
238 // Extracts all joinable properties from 'Conversation' document
239 ICING_ASSERT_OK_AND_ASSIGN(
240 JoinablePropertyGroup joinable_property_group,
241 schema_type_manager->joinable_property_manager()
242 .ExtractJoinableProperties(conversation_document_));
243
244 // Qualified Id joinable properties
245 EXPECT_THAT(joinable_property_group.qualified_id_properties, SizeIs(3));
246
247 EXPECT_THAT(joinable_property_group.qualified_id_properties[0].metadata,
248 EqualsJoinablePropertyMetadata(
249 /*expected_id=*/0,
250 /*expected_property_path=*/"emails.receiverQualifiedId",
251 CreateReceiverQualifiedIdPropertyConfig()));
252 EXPECT_THAT(joinable_property_group.qualified_id_properties[0].values,
253 ElementsAre("pkg$db/ns#Person2"));
254
255 EXPECT_THAT(joinable_property_group.qualified_id_properties[1].metadata,
256 EqualsJoinablePropertyMetadata(
257 /*expected_id=*/1,
258 /*expected_property_path=*/"emails.senderQualifiedId",
259 CreateSenderQualifiedIdPropertyConfig()));
260 EXPECT_THAT(joinable_property_group.qualified_id_properties[1].values,
261 ElementsAre("pkg$db/ns#Person1"));
262
263 EXPECT_THAT(
264 joinable_property_group.qualified_id_properties[2].metadata,
265 EqualsJoinablePropertyMetadata(
266 /*expected_id=*/2, /*expected_property_path=*/"groupQualifiedId",
267 CreateGroupQualifiedIdPropertyConfig()));
268 EXPECT_THAT(joinable_property_group.qualified_id_properties[2].values,
269 ElementsAre("pkg$db/ns#GroupQualifiedId1"));
270 }
271
TEST_F(JoinablePropertyManagerTest,ExtractJoinablePropertiesShouldIgnoreEmptyContents)272 TEST_F(JoinablePropertyManagerTest,
273 ExtractJoinablePropertiesShouldIgnoreEmptyContents) {
274 // Use SchemaTypeManager factory method to instantiate
275 // JoinablePropertyManager.
276 ICING_ASSERT_OK_AND_ASSIGN(
277 std::unique_ptr<SchemaTypeManager> schema_type_manager,
278 SchemaTypeManager::Create(type_config_map_, schema_type_mapper_.get()));
279
280 // Create an email document without receiverQualifiedId.
281 DocumentProto another_email_document =
282 DocumentBuilder()
283 .SetKey("icing", "email/2")
284 .SetSchema(kTypeEmail)
285 .AddStringProperty(kPropertySubject, "the subject")
286 .AddStringProperty(kPropertyText, "the text")
287 .AddBytesProperty(kPropertyAttachment, "attachment")
288 .AddStringProperty(kPropertySenderQualifiedId, "pkg$db/ns#Person1")
289 .AddInt64Property(kPropertyTimestamp, kDefaultTimestamp)
290 .Build();
291
292 ICING_ASSERT_OK_AND_ASSIGN(
293 JoinablePropertyGroup joinable_property_group,
294 schema_type_manager->joinable_property_manager()
295 .ExtractJoinableProperties(another_email_document));
296
297 // ExtractJoinableProperties should ignore receiverQualifiedId and not append
298 // a JoinableProperty instance of it into the vector.
299 EXPECT_THAT(joinable_property_group.qualified_id_properties, SizeIs(1));
300 EXPECT_THAT(
301 joinable_property_group.qualified_id_properties[0].metadata,
302 EqualsJoinablePropertyMetadata(
303 /*expected_id=*/1, /*expected_property_path=*/"senderQualifiedId",
304 CreateSenderQualifiedIdPropertyConfig()));
305 EXPECT_THAT(joinable_property_group.qualified_id_properties[0].values,
306 ElementsAre("pkg$db/ns#Person1"));
307 }
308
TEST_F(JoinablePropertyManagerTest,GetJoinablePropertyMetadata)309 TEST_F(JoinablePropertyManagerTest, GetJoinablePropertyMetadata) {
310 // Use SchemaTypeManager factory method to instantiate
311 // JoinablePropertyManager.
312 ICING_ASSERT_OK_AND_ASSIGN(
313 std::unique_ptr<SchemaTypeManager> schema_type_manager,
314 SchemaTypeManager::Create(type_config_map_, schema_type_mapper_.get()));
315
316 // Email (joinable property id -> joinable property path):
317 // 0 -> receiverQualifiedId
318 // 1 -> senderQualifiedId
319 EXPECT_THAT(
320 schema_type_manager->joinable_property_manager()
321 .GetJoinablePropertyMetadata(/*schema_type_id=*/0,
322 /*joinable_property_id=*/0),
323 IsOkAndHolds(Pointee(EqualsJoinablePropertyMetadata(
324 /*expected_id=*/0, /*expected_property_path=*/"receiverQualifiedId",
325 CreateReceiverQualifiedIdPropertyConfig()))));
326 EXPECT_THAT(
327 schema_type_manager->joinable_property_manager()
328 .GetJoinablePropertyMetadata(/*schema_type_id=*/0,
329 /*joinable_property_id=*/1),
330 IsOkAndHolds(Pointee(EqualsJoinablePropertyMetadata(
331 /*expected_id=*/1, /*expected_property_path=*/"senderQualifiedId",
332 CreateSenderQualifiedIdPropertyConfig()))));
333
334 // Conversation (joinable property id -> joinable property path):
335 // 0 -> emails.receiverQualifiedId
336 // 1 -> emails.senderQualifiedId
337 // 2 -> groupQualifiedId
338 EXPECT_THAT(schema_type_manager->joinable_property_manager()
339 .GetJoinablePropertyMetadata(/*schema_type_id=*/1,
340 /*joinable_property_id=*/0),
341 IsOkAndHolds(Pointee(EqualsJoinablePropertyMetadata(
342 /*expected_id=*/0,
343 /*expected_property_path=*/"emails.receiverQualifiedId",
344 CreateReceiverQualifiedIdPropertyConfig()))));
345 EXPECT_THAT(schema_type_manager->joinable_property_manager()
346 .GetJoinablePropertyMetadata(/*schema_type_id=*/1,
347 /*joinable_property_id=*/1),
348 IsOkAndHolds(Pointee(EqualsJoinablePropertyMetadata(
349 /*expected_id=*/1,
350 /*expected_property_path=*/"emails.senderQualifiedId",
351 CreateSenderQualifiedIdPropertyConfig()))));
352 EXPECT_THAT(
353 schema_type_manager->joinable_property_manager()
354 .GetJoinablePropertyMetadata(/*schema_type_id=*/1,
355 /*joinable_property_id=*/2),
356 IsOkAndHolds(Pointee(EqualsJoinablePropertyMetadata(
357 /*expected_id=*/2, /*expected_property_path=*/"groupQualifiedId",
358 CreateGroupQualifiedIdPropertyConfig()))));
359 }
360
TEST_F(JoinablePropertyManagerTest,GetJoinablePropertyMetadataInvalidSchemaTypeId)361 TEST_F(JoinablePropertyManagerTest,
362 GetJoinablePropertyMetadataInvalidSchemaTypeId) {
363 // Use SchemaTypeManager factory method to instantiate
364 // JoinablePropertyManager.
365 ICING_ASSERT_OK_AND_ASSIGN(
366 std::unique_ptr<SchemaTypeManager> schema_type_manager,
367 SchemaTypeManager::Create(type_config_map_, schema_type_mapper_.get()));
368 ASSERT_THAT(type_config_map_, SizeIs(2));
369
370 EXPECT_THAT(schema_type_manager->joinable_property_manager()
371 .GetJoinablePropertyMetadata(/*schema_type_id=*/-1,
372 /*joinable_property_id=*/0),
373 StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT));
374 EXPECT_THAT(schema_type_manager->joinable_property_manager()
375 .GetJoinablePropertyMetadata(/*schema_type_id=*/2,
376 /*joinable_property_id=*/0),
377 StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT));
378 }
379
TEST_F(JoinablePropertyManagerTest,GetJoinablePropertyMetadataInvalidJoinablePropertyId)380 TEST_F(JoinablePropertyManagerTest,
381 GetJoinablePropertyMetadataInvalidJoinablePropertyId) {
382 // Use SchemaTypeManager factory method to instantiate
383 // JoinablePropertyManager.
384 ICING_ASSERT_OK_AND_ASSIGN(
385 std::unique_ptr<SchemaTypeManager> schema_type_manager,
386 SchemaTypeManager::Create(type_config_map_, schema_type_mapper_.get()));
387
388 // Email (joinable property id -> joinable property path):
389 // 0 -> receiverQualifiedId
390 // 1 -> senderQualifiedId
391 EXPECT_THAT(schema_type_manager->joinable_property_manager()
392 .GetJoinablePropertyMetadata(/*schema_type_id=*/0,
393 /*joinable_property_id=*/-1),
394 StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT));
395 EXPECT_THAT(schema_type_manager->joinable_property_manager()
396 .GetJoinablePropertyMetadata(/*schema_type_id=*/0,
397 /*joinable_property_id=*/2),
398 StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT));
399
400 // Conversation (joinable property id -> joinable property path):
401 // 0 -> emails.receiverQualifiedId
402 // 1 -> emails.senderQualifiedId
403 // 2 -> groupQualifiedId
404 EXPECT_THAT(schema_type_manager->joinable_property_manager()
405 .GetJoinablePropertyMetadata(/*schema_type_id=*/1,
406 /*joinable_property_id=*/-1),
407 StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT));
408 EXPECT_THAT(schema_type_manager->joinable_property_manager()
409 .GetJoinablePropertyMetadata(/*schema_type_id=*/1,
410 /*joinable_property_id=*/3),
411 StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT));
412 }
413
TEST_F(JoinablePropertyManagerTest,GetJoinablePropertyMetadataByPath)414 TEST_F(JoinablePropertyManagerTest, GetJoinablePropertyMetadataByPath) {
415 // Use SchemaTypeManager factory method to instantiate
416 // JoinablePropertyManager.
417 ICING_ASSERT_OK_AND_ASSIGN(
418 std::unique_ptr<SchemaTypeManager> schema_type_manager,
419 SchemaTypeManager::Create(type_config_map_, schema_type_mapper_.get()));
420
421 // Email (joinable property id -> joinable property path):
422 // 0 -> receiverQualifiedId
423 // 1 -> senderQualifiedId
424 EXPECT_THAT(
425 schema_type_manager->joinable_property_manager()
426 .GetJoinablePropertyMetadata(/*schema_type_id=*/0,
427 "receiverQualifiedId"),
428 IsOkAndHolds(Pointee(EqualsJoinablePropertyMetadata(
429 /*expected_id=*/0, /*expected_property_path=*/"receiverQualifiedId",
430 CreateReceiverQualifiedIdPropertyConfig()))));
431 EXPECT_THAT(
432 schema_type_manager->joinable_property_manager()
433 .GetJoinablePropertyMetadata(/*schema_type_id=*/0,
434 "senderQualifiedId"),
435 IsOkAndHolds(Pointee(EqualsJoinablePropertyMetadata(
436 /*expected_id=*/1, /*expected_property_path=*/"senderQualifiedId",
437 CreateSenderQualifiedIdPropertyConfig()))));
438
439 // Conversation (joinable property id -> joinable property path):
440 // 0 -> emails.receiverQualifiedId
441 // 1 -> emails.senderQualifiedId
442 // 2 -> groupQualifiedId
443 EXPECT_THAT(schema_type_manager->joinable_property_manager()
444 .GetJoinablePropertyMetadata(/*schema_type_id=*/1,
445 "emails.receiverQualifiedId"),
446 IsOkAndHolds(Pointee(EqualsJoinablePropertyMetadata(
447 /*expected_id=*/0,
448 /*expected_property_path=*/"emails.receiverQualifiedId",
449 CreateReceiverQualifiedIdPropertyConfig()))));
450 EXPECT_THAT(schema_type_manager->joinable_property_manager()
451 .GetJoinablePropertyMetadata(/*schema_type_id=*/1,
452 "emails.senderQualifiedId"),
453 IsOkAndHolds(Pointee(EqualsJoinablePropertyMetadata(
454 /*expected_id=*/1,
455 /*expected_property_path=*/"emails.senderQualifiedId",
456 CreateSenderQualifiedIdPropertyConfig()))));
457 EXPECT_THAT(
458 schema_type_manager->joinable_property_manager()
459 .GetJoinablePropertyMetadata(/*schema_type_id=*/1,
460 "groupQualifiedId"),
461 IsOkAndHolds(Pointee(EqualsJoinablePropertyMetadata(
462 /*expected_id=*/2, /*expected_property_path=*/"groupQualifiedId",
463 CreateGroupQualifiedIdPropertyConfig()))));
464 }
465
TEST_F(JoinablePropertyManagerTest,GetJoinablePropertyMetadataByPathInvalidSchemaTypeId)466 TEST_F(JoinablePropertyManagerTest,
467 GetJoinablePropertyMetadataByPathInvalidSchemaTypeId) {
468 // Use SchemaTypeManager factory method to instantiate
469 // JoinablePropertyManager.
470 ICING_ASSERT_OK_AND_ASSIGN(
471 std::unique_ptr<SchemaTypeManager> schema_type_manager,
472 SchemaTypeManager::Create(type_config_map_, schema_type_mapper_.get()));
473 ASSERT_THAT(type_config_map_, SizeIs(2));
474
475 EXPECT_THAT(schema_type_manager->joinable_property_manager()
476 .GetJoinablePropertyMetadata(/*schema_type_id=*/-1,
477 "receiverQualifiedId"),
478 StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT));
479 EXPECT_THAT(schema_type_manager->joinable_property_manager()
480 .GetJoinablePropertyMetadata(/*schema_type_id=*/2,
481 "receiverQualifiedId"),
482 StatusIs(libtextclassifier3::StatusCode::INVALID_ARGUMENT));
483 }
484
TEST_F(JoinablePropertyManagerTest,GetJoinablePropertyMetadataByPathNotExist)485 TEST_F(JoinablePropertyManagerTest, GetJoinablePropertyMetadataByPathNotExist) {
486 // Use SchemaTypeManager factory method to instantiate
487 // JoinablePropertyManager.
488 ICING_ASSERT_OK_AND_ASSIGN(
489 std::unique_ptr<SchemaTypeManager> schema_type_manager,
490 SchemaTypeManager::Create(type_config_map_, schema_type_mapper_.get()));
491
492 EXPECT_THAT(
493 schema_type_manager->joinable_property_manager()
494 .GetJoinablePropertyMetadata(/*schema_type_id=*/0, "nonExistingPath"),
495 IsOkAndHolds(IsNull()));
496 EXPECT_THAT(schema_type_manager->joinable_property_manager()
497 .GetJoinablePropertyMetadata(/*schema_type_id=*/1,
498 "emails.nonExistingPath"),
499 IsOkAndHolds(IsNull()));
500 }
501
502 // Note: valid GetMetadataList has been tested in
503 // JoinablePropertyManagerBuildTest.
TEST_F(JoinablePropertyManagerTest,GetMetadataListInvalidSchemaTypeName)504 TEST_F(JoinablePropertyManagerTest, GetMetadataListInvalidSchemaTypeName) {
505 // Use SchemaTypeManager factory method to instantiate
506 // JoinablePropertyManager.
507 ICING_ASSERT_OK_AND_ASSIGN(
508 std::unique_ptr<SchemaTypeManager> schema_type_manager,
509 SchemaTypeManager::Create(type_config_map_, schema_type_mapper_.get()));
510
511 EXPECT_THAT(schema_type_manager->joinable_property_manager().GetMetadataList(
512 "NonExistingSchemaTypeName"),
513 StatusIs(libtextclassifier3::StatusCode::NOT_FOUND));
514 }
515
516 } // namespace
517
518 } // namespace lib
519 } // namespace icing
520