@@ -51,6 +51,10 @@ void mock_deletion_user_mqtt_topic(user_credential_user_unique_id_t user_id);
5151void mock_deletion_cred_mqtt_topic (user_credential_user_unique_id_t user_id,
5252 user_credential_type_t credential_type,
5353 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+
5458
5559// Keep a reference to the mqtt topics we want to test
5660// Stored as <topic, payload>
@@ -60,6 +64,8 @@ static std::vector<std::tuple<user_credential_user_unique_id_t,
6064 user_credential_type_t ,
6165 user_credential_slot_t >>
6266 created_credential_ids;
67+ static std::vector<user_credential_type_t >
68+ created_supported_credential_types;
6369
6470// Callback functions
6571// clang-format off
@@ -132,6 +138,11 @@ int suiteTearDown(int num_failures)
132138// / Called before each and every test
133139void setUp ()
134140{
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+ }
135146 // Check if any users that need to be removed
136147 for (auto user_id: created_user_id) {
137148 // Check if MQTT topics for deletion are correctly published
@@ -143,6 +154,8 @@ void setUp()
143154 std::get<2 >(cred_id));
144155 }
145156
157+
158+
146159 zpc_attribute_store_test_helper_create_network ();
147160
148161 // Intercept the dotdot MQTT callbacks
@@ -154,7 +167,7 @@ void setUp()
154167 mqtt_topics.clear ();
155168 created_user_id.clear ();
156169 created_credential_ids.clear ();
157-
170+ created_supported_credential_types. clear ();
158171 // clang-format off
159172 // User
160173 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()
168181
169182 // Run the component init
170183 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 ();
171190}
172191
173192// ///////////////////////////////////////////////////////////////////////
174193// Mqtt topics helpers
175194// ///////////////////////////////////////////////////////////////////////
176- std::string get_base_topic ()
195+ std::string get_base_topic (bool include_user= true )
177196{
197+ const std::string user_str = include_user ? " /User" : " " ;
178198 const std::string base
179- = " ucl/by-unid/%1%/ep%2%/UserCredential/Attributes/User " ;
199+ = " ucl/by-unid/%1%/ep%2%/UserCredential/Attributes%3% " ;
180200 return (boost::format (base) % supporting_node_unid
181- % (unsigned int )endpoint_id)
201+ % (unsigned int )endpoint_id % user_str)
182202 .str ();
183203}
184204
205+
206+
185207std::string
186208 get_user_attribute_mqtt_topic (user_credential_user_unique_id_t user_unique_id,
187209 const std::string &attribute_name)
@@ -205,6 +227,17 @@ std::string
205227 .str ();
206228}
207229
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+
208241} // extern "C"
209242
210243template <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,
250283 mqtt_topics.back ().second .size (),
251284 true );
252285}
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)});
253295
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+ }
254301void mock_deletion_user_mqtt_topic (user_credential_user_unique_id_t user_id)
255302{
256303 // 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,
292339 true );
293340 }
294341}
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+
295465// ///////////////////////////////////////////////////////////////////////
296466// HELPERS
297467// ///////////////////////////////////////////////////////////////////////
@@ -1100,7 +1270,7 @@ void test_user_credential_cluster_add_credential_others_happy_case()
11001270{
11011271 // Simulate user
11021272 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 ;
11041274 user_credential_slot_t credential_slot = 1 ;
11051275 const char *credential_data = " hunter2" ;
11061276
@@ -1402,13 +1572,6 @@ void test_user_credential_cluster_delete_credential_happy_case()
14021572
14031573void test_user_credential_cluster_test_user_command_support_happy_case ()
14041574{
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-
14121575 // We don't care about those value it should not matter here
14131576 user_credential_user_unique_id_t user_unique_id = 12 ;
14141577 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()
14661629 UserNameEncodingType user_name_encoding = ZCL_USER_NAME_ENCODING_TYPE_ASCII;
14671630 const char *user_name = " Test User" ;
14681631
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+
14691641 TEST_ASSERT_EQUAL_MESSAGE (
14701642 SL_STATUS_FAIL,
14711643 add_user_command (supporting_node_unid,
@@ -1478,7 +1650,7 @@ void test_user_credential_cluster_test_user_command_not_supported_happy_case()
14781650 user_name,
14791651 expiring_timeout,
14801652 user_name_encoding),
1481- " Add user should not be supported" );
1653+ " Check value : Add user should not be supported" );
14821654
14831655 TEST_ASSERT_EQUAL_MESSAGE (
14841656 SL_STATUS_FAIL,
0 commit comments