@@ -51,6 +51,10 @@ void mock_deletion_user_mqtt_topic(user_credential_user_unique_id_t user_id);
51
51
void mock_deletion_cred_mqtt_topic (user_credential_user_unique_id_t user_id,
52
52
user_credential_type_t credential_type,
53
53
user_credential_slot_t credential_slot);
54
+ void mock_deletion_cred_rule_mqtt_topic (user_credential_type_t credential_type);
55
+ void setup_user_capabilities ();
56
+ void setup_cred_capabilities ();
57
+
54
58
55
59
// Keep a reference to the mqtt topics we want to test
56
60
// Stored as <topic, payload>
@@ -60,6 +64,8 @@ static std::vector<std::tuple<user_credential_user_unique_id_t,
60
64
user_credential_type_t ,
61
65
user_credential_slot_t >>
62
66
created_credential_ids;
67
+ static std::vector<user_credential_type_t >
68
+ created_supported_credential_types;
63
69
64
70
// Callback functions
65
71
// clang-format off
@@ -132,6 +138,11 @@ int suiteTearDown(int num_failures)
132
138
// / Called before each and every test
133
139
void setUp ()
134
140
{
141
+ // WARNING : Order matters here
142
+ // Check if credential rules need to be removed
143
+ for (auto cred_type: created_supported_credential_types) {
144
+ mock_deletion_cred_rule_mqtt_topic (cred_type);
145
+ }
135
146
// Check if any users that need to be removed
136
147
for (auto user_id: created_user_id) {
137
148
// Check if MQTT topics for deletion are correctly published
@@ -143,6 +154,8 @@ void setUp()
143
154
std::get<2 >(cred_id));
144
155
}
145
156
157
+
158
+
146
159
zpc_attribute_store_test_helper_create_network ();
147
160
148
161
// Intercept the dotdot MQTT callbacks
@@ -154,7 +167,7 @@ void setUp()
154
167
mqtt_topics.clear ();
155
168
created_user_id.clear ();
156
169
created_credential_ids.clear ();
157
-
170
+ created_supported_credential_types. clear ();
158
171
// clang-format off
159
172
// User
160
173
uic_mqtt_dotdot_user_credential_add_user_callback_set_Stub (&uic_mqtt_dotdot_user_credential_add_user_callback_set_stub);
@@ -168,20 +181,29 @@ void setUp()
168
181
169
182
// Run the component init
170
183
TEST_ASSERT_EQUAL (SL_STATUS_OK, user_credential_cluster_server_init ());
184
+
185
+ // We are not here to test user capabilities, so we need to set them up to
186
+ // accept our test data
187
+ setup_user_capabilities ();
188
+ // Need to call this after init() to have the mqtt callback initialized
189
+ setup_cred_capabilities ();
171
190
}
172
191
173
192
// ///////////////////////////////////////////////////////////////////////
174
193
// Mqtt topics helpers
175
194
// ///////////////////////////////////////////////////////////////////////
176
- std::string get_base_topic ()
195
+ std::string get_base_topic (bool include_user= true )
177
196
{
197
+ const std::string user_str = include_user ? " /User" : " " ;
178
198
const std::string base
179
- = " ucl/by-unid/%1%/ep%2%/UserCredential/Attributes/User " ;
199
+ = " ucl/by-unid/%1%/ep%2%/UserCredential/Attributes%3% " ;
180
200
return (boost::format (base) % supporting_node_unid
181
- % (unsigned int )endpoint_id)
201
+ % (unsigned int )endpoint_id % user_str)
182
202
.str ();
183
203
}
184
204
205
+
206
+
185
207
std::string
186
208
get_user_attribute_mqtt_topic (user_credential_user_unique_id_t user_unique_id,
187
209
const std::string &attribute_name)
@@ -205,6 +227,17 @@ std::string
205
227
.str ();
206
228
}
207
229
230
+ std::string
231
+ get_cred_rule_mqtt_topic (user_credential_type_t credential_type,
232
+ const std::string &attribute_name)
233
+ {
234
+ const std::string base = " %1%/Credentials/%2%/%3%/Reported" ;
235
+ return (boost::format (base) % get_base_topic (false )
236
+ % cred_type_get_enum_value_name (credential_type)
237
+ % attribute_name)
238
+ .str ();
239
+ }
240
+
208
241
} // extern "C"
209
242
210
243
template <typename T> std::string get_payload (T value)
@@ -250,7 +283,21 @@ void mock_expected_cred_mqtt_topic(user_credential_user_unique_id_t user_id,
250
283
mqtt_topics.back ().second .size (),
251
284
true );
252
285
}
286
+ template <typename T>
287
+ void mock_expected_cred_rule_mqtt_topic (user_credential_type_t credential_type,
288
+ const std::string &attribute_name,
289
+ T payload_value)
290
+ {
291
+ // This way we make sure that we have valid reference to our strings
292
+ mqtt_topics.push_back (
293
+ {get_cred_rule_mqtt_topic (credential_type, attribute_name),
294
+ get_payload<T>(payload_value)});
253
295
296
+ uic_mqtt_publish_Expect (mqtt_topics.back ().first .c_str (),
297
+ mqtt_topics.back ().second .c_str (),
298
+ mqtt_topics.back ().second .size (),
299
+ true );
300
+ }
254
301
void mock_deletion_user_mqtt_topic (user_credential_user_unique_id_t user_id)
255
302
{
256
303
// WARNING : Order here matters based on their initialization order in the add_complete_user function
@@ -292,6 +339,129 @@ void mock_deletion_cred_mqtt_topic(user_credential_user_unique_id_t user_id,
292
339
true );
293
340
}
294
341
}
342
+
343
+ void mock_deletion_cred_rule_mqtt_topic (user_credential_type_t credential_type)
344
+ {
345
+ // WARNING : Order here matters based on their initialization order in the add_complete_credential function
346
+ std::vector<std::string> attribute_names = {" ReadBackSupport" ,
347
+ " SupportedSlotCount" ,
348
+ " CredentialMinLength" ,
349
+ " CredentialMaxLength" };
350
+ for (auto &attribute_name: attribute_names) {
351
+ mqtt_topics.push_back (
352
+ {get_cred_rule_mqtt_topic (credential_type, attribute_name), " " });
353
+ uic_mqtt_publish_Expect (mqtt_topics.back ().first .c_str (),
354
+ mqtt_topics.back ().second .c_str (),
355
+ mqtt_topics.back ().second .size (),
356
+ true );
357
+ }
358
+ }
359
+ // ///////////////////////////////////////////////////////////////////////
360
+ // Capabilities Helper
361
+ // ///////////////////////////////////////////////////////////////////////
362
+ void setup_user_capabilities () {
363
+ uint16_t number_of_users = 12 ;
364
+ user_credential_supported_credential_rules_t cred_rule_bitmask = 0x0F ;
365
+ uint8_t username_max_length = 112 ;
366
+ uint8_t support_user_schedule = 0 ;
367
+ uint8_t support_all_users_checksum = 0 ;
368
+ uint8_t support_user_checksum = 0 ;
369
+ user_credential_supported_user_type_bitmask_t supported_user_types_bitmask
370
+ = 0xFF ;
371
+
372
+ attribute_store_emplace (endpoint_id_node,
373
+ ATTRIBUTE (NUMBER_OF_USERS),
374
+ &number_of_users,
375
+ sizeof (number_of_users));
376
+
377
+ attribute_store_emplace (endpoint_id_node,
378
+ ATTRIBUTE (SUPPORTED_CREDENTIAL_RULES),
379
+ &cred_rule_bitmask,
380
+ sizeof (cred_rule_bitmask));
381
+
382
+ attribute_store_emplace (endpoint_id_node,
383
+ ATTRIBUTE (MAX_USERNAME_LENGTH),
384
+ &username_max_length,
385
+ sizeof (username_max_length));
386
+
387
+ attribute_store_emplace (endpoint_id_node,
388
+ ATTRIBUTE (SUPPORT_USER_SCHEDULE),
389
+ &support_user_schedule,
390
+ sizeof (support_user_schedule));
391
+
392
+ attribute_store_emplace (endpoint_id_node,
393
+ ATTRIBUTE (SUPPORT_ALL_USERS_CHECKSUM),
394
+ &support_all_users_checksum,
395
+ sizeof (support_all_users_checksum));
396
+
397
+ attribute_store_emplace (endpoint_id_node,
398
+ ATTRIBUTE (SUPPORT_USER_CHECKSUM),
399
+ &support_user_checksum,
400
+ sizeof (support_user_checksum));
401
+
402
+ attribute_store_emplace (endpoint_id_node,
403
+ ATTRIBUTE (SUPPORTED_USER_TYPES),
404
+ &supported_user_types_bitmask,
405
+ sizeof (supported_user_types_bitmask));
406
+ }
407
+
408
+ void setup_cred_capabilities () {
409
+
410
+ // Supports ZCL_CRED_TYPE_PIN_CODE..ZCL_CRED_TYPE_BLE
411
+ // Adjust if needed, we don't need to test all types and this outputs a lot of noise on the logs
412
+ uint8_t max_cred_type = ZCL_CRED_TYPE_BLE;
413
+ for (uint8_t i=ZCL_CRED_TYPE_PIN_CODE;i<=max_cred_type;i++) {
414
+ user_credential_type_t cred_type
415
+ = static_cast <user_credential_type_t >(i);
416
+
417
+ auto supported_cred_type_node
418
+ = attribute_store_emplace (endpoint_id_node,
419
+ ATTRIBUTE (SUPPORTED_CREDENTIAL_TYPE),
420
+ &cred_type,
421
+ sizeof (cred_type));
422
+ uint8_t crb_support = 1 ;
423
+ uint16_t slot_supported = 0xFFFF ;
424
+ uint16_t cred_min_length = 0 ;
425
+ uint16_t cred_max_length = 0xFF ;
426
+
427
+ mock_expected_cred_rule_mqtt_topic (cred_type,
428
+ " ReadBackSupport" ,
429
+ (bool )crb_support);
430
+ attribute_store_emplace (supported_cred_type_node,
431
+ ATTRIBUTE (CREDENTIAL_LEARN_READ_BACK_SUPPORT),
432
+ &crb_support,
433
+ sizeof (crb_support));
434
+
435
+ mock_expected_cred_rule_mqtt_topic (cred_type,
436
+ " SupportedSlotCount" ,
437
+ slot_supported);
438
+
439
+ attribute_store_emplace (supported_cred_type_node,
440
+ ATTRIBUTE (CREDENTIAL_SUPPORTED_SLOT_COUNT),
441
+ &slot_supported,
442
+ sizeof (slot_supported));
443
+ mock_expected_cred_rule_mqtt_topic (cred_type,
444
+ " CredentialMinLength" ,
445
+ cred_min_length);
446
+
447
+ attribute_store_emplace (supported_cred_type_node,
448
+ ATTRIBUTE (CREDENTIAL_MIN_LENGTH),
449
+ &cred_min_length,
450
+ sizeof (cred_min_length));
451
+
452
+ mock_expected_cred_rule_mqtt_topic (cred_type,
453
+ " CredentialMaxLength" ,
454
+ cred_max_length);
455
+ attribute_store_emplace (supported_cred_type_node,
456
+ ATTRIBUTE (CREDENTIAL_MAX_LENGTH),
457
+ &cred_max_length,
458
+ sizeof (cred_max_length));
459
+
460
+ // Will allow to test deletion of attributes
461
+ created_supported_credential_types.push_back (cred_type);
462
+ }
463
+ }
464
+
295
465
// ///////////////////////////////////////////////////////////////////////
296
466
// HELPERS
297
467
// ///////////////////////////////////////////////////////////////////////
@@ -1100,7 +1270,7 @@ void test_user_credential_cluster_add_credential_others_happy_case()
1100
1270
{
1101
1271
// Simulate user
1102
1272
user_credential_user_unique_id_t user_unique_id = 12 ;
1103
- CredType credential_type = CredType::ZCL_CRED_TYPE_NFC ;
1273
+ CredType credential_type = CredType::ZCL_CRED_TYPE_RFID_CODE ;
1104
1274
user_credential_slot_t credential_slot = 1 ;
1105
1275
const char *credential_data = " hunter2" ;
1106
1276
@@ -1402,13 +1572,6 @@ void test_user_credential_cluster_delete_credential_happy_case()
1402
1572
1403
1573
void test_user_credential_cluster_test_user_command_support_happy_case ()
1404
1574
{
1405
- // Emplace checked attributes
1406
- uint16_t user_count = 2 ;
1407
- attribute_store_emplace (endpoint_id_node,
1408
- ATTRIBUTE (NUMBER_OF_USERS),
1409
- &user_count,
1410
- sizeof (user_count));
1411
-
1412
1575
// We don't care about those value it should not matter here
1413
1576
user_credential_user_unique_id_t user_unique_id = 12 ;
1414
1577
UserTypeEnum user_type = ZCL_USER_TYPE_ENUM_DISPOSABLE_USER;
@@ -1466,6 +1629,15 @@ void test_user_credential_cluster_test_user_command_not_supported_happy_case()
1466
1629
UserNameEncodingType user_name_encoding = ZCL_USER_NAME_ENCODING_TYPE_ASCII;
1467
1630
const char *user_name = " Test User" ;
1468
1631
1632
+ // We don't want anything in the tree for this test
1633
+ // This way we can make support check fails
1634
+ // We need to inform the MQTT of the deleted credential type rules
1635
+ for (auto cred_type: created_supported_credential_types) {
1636
+ mock_deletion_cred_rule_mqtt_topic (cred_type);
1637
+ }
1638
+ // Delete all the nodes
1639
+ attribute_store_delete_all_children (endpoint_id_node);
1640
+
1469
1641
TEST_ASSERT_EQUAL_MESSAGE (
1470
1642
SL_STATUS_FAIL,
1471
1643
add_user_command (supporting_node_unid,
@@ -1478,7 +1650,7 @@ void test_user_credential_cluster_test_user_command_not_supported_happy_case()
1478
1650
user_name,
1479
1651
expiring_timeout,
1480
1652
user_name_encoding),
1481
- " Add user should not be supported" );
1653
+ " Check value : Add user should not be supported" );
1482
1654
1483
1655
TEST_ASSERT_EQUAL_MESSAGE (
1484
1656
SL_STATUS_FAIL,
0 commit comments