@@ -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