Fix identityref passing through sysrepo and NETCONF

Change-Id: Ie0f712befe56c2fcea52401a12c33812b7fb9066
diff --git a/src/leaf_data.hpp b/src/leaf_data.hpp
index 68705d0..2f84a05 100644
--- a/src/leaf_data.hpp
+++ b/src/leaf_data.hpp
@@ -54,7 +54,7 @@
     leaf_data_binary_data;
 
 auto const leaf_data_identityRef_data_def =
-    -module  >> node_identifier;
+    -module >> node_identifier;
 
 // TODO: get rid of this and use leaf_data_identityRef_data directly
 auto const leaf_data_identityRef_def =
diff --git a/src/libyang_utils.cpp b/src/libyang_utils.cpp
index 9051e16..3b924ad 100644
--- a/src/libyang_utils.cpp
+++ b/src/libyang_utils.cpp
@@ -27,6 +27,8 @@
         return std::string(value->string());
     case LY_TYPE_ENUM:
         return enum_{std::string(value->enm()->name())};
+    case LY_TYPE_IDENT:
+        return identityRef_{value->ident()->module()->name(), value->ident()->name()};
     case LY_TYPE_BINARY:
         return std::string{value->binary()};
     case LY_TYPE_DEC64:
diff --git a/src/sysrepo_access.cpp b/src/sysrepo_access.cpp
index 7115ad7..bc7431b 100644
--- a/src/sysrepo_access.cpp
+++ b/src/sysrepo_access.cpp
@@ -40,6 +40,11 @@
         return std::string(value->data()->get_string());
     case SR_ENUM_T:
         return enum_{std::string(value->data()->get_enum())};
+    case SR_IDENTITYREF_T:
+    {
+        auto pair = splitModuleNode(value->data()->get_identityref());
+        return identityRef_{*pair.first, pair.second};
+    }
     case SR_DECIMAL64_T:
         return value->data()->get_decimal64();
     case SR_CONTAINER_T:
@@ -66,7 +71,7 @@
 
     sysrepo::S_Val operator()(const identityRef_& value) const
     {
-        auto res = value.m_prefix.value().m_name + ":" + value.m_value;
+        auto res = value.m_prefix ? (value.m_prefix.value().m_name + ":" + value.m_value) : value.m_value;
         return std::make_shared<sysrepo::Val>(res.c_str(), SR_IDENTITYREF_T);
     }
 
diff --git a/src/utils.cpp b/src/utils.cpp
index dbfc647..665aedd 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -165,7 +165,7 @@
 
     std::string operator()(const identityRef_& data) const
     {
-        return data.m_prefix.value().m_name + ":" + data.m_value;
+        return data.m_prefix ? (data.m_prefix.value().m_name + ":" + data.m_value) : data.m_value;
     }
 
     std::string operator()(const special_& data) const
diff --git a/tests/datastore_access.cpp b/tests/datastore_access.cpp
index 6979dba..a1c8906 100644
--- a/tests/datastore_access.cpp
+++ b/tests/datastore_access.cpp
@@ -330,6 +330,24 @@
         REQUIRE(datastore.getItems("/example-schema:unionIntString") == expected);
     }
 
+    SECTION("identityref") {
+        datastore.setLeaf("/example-schema:beast", identityRef_{"example-schema", "Mammal"});
+        REQUIRE_CALL(mock, write("/example-schema:beast", std::nullopt, "example-schema:Mammal"s));
+        datastore.commitChanges();
+        DatastoreAccess::Tree expected {
+            {"/example-schema:beast", identityRef_{"example-schema", "Mammal"}},
+        };
+        REQUIRE(datastore.getItems("/example-schema:beast") == expected);
+
+        datastore.setLeaf("/example-schema:beast", identityRef_{"Whale"});
+        REQUIRE_CALL(mock, write("/example-schema:beast", "example-schema:Mammal", "example-schema:Whale"s));
+        datastore.commitChanges();
+        expected = {
+            {"/example-schema:beast", identityRef_{"example-schema", "Whale"}},
+        };
+        REQUIRE(datastore.getItems("/example-schema:beast") == expected);
+    }
+
     SECTION("operational data")
     {
         MockDataSupplier mockOpsData;
diff --git a/tests/example-schema.yang b/tests/example-schema.yang
index ac7724a..a24b891 100644
--- a/tests/example-schema.yang
+++ b/tests/example-schema.yang
@@ -214,4 +214,29 @@
         type int32;
         config false;
     }
+
+    identity Animal {
+    }
+
+    identity Mammal {
+        base "Animal";
+    }
+
+    identity Dog {
+        base "Mammal";
+    }
+
+    identity Whale {
+        base "Mammal";
+    }
+
+    identity Velociraptor {
+        base "Animal";
+    }
+
+    leaf beast {
+        type identityref {
+            base "Animal";
+        }
+    }
 }