diff --git a/test/unitTest/Makefile.am b/test/unitTest/Makefile.am
index 9ca3e778e398346fd5ba51b3b572b6d5b4926cce..fe69fa2b54207d24244cfe184954a5c686f7fbb9 100644
--- a/test/unitTest/Makefile.am
+++ b/test/unitTest/Makefile.am
@@ -133,6 +133,12 @@ ut_audio_frame_resizer_SOURCES = media/audio/test_audio_frame_resizer.cpp common
 check_PROGRAMS += ut_call
 ut_call_SOURCES = call/call.cpp common.cpp
 
+#
+# SIPcall
+#
+check_PROGRAMS += ut_sipcall
+ut_sipcall_SOURCES = call/sipcall.cpp common.cpp
+
 #
 # recorder
 #
diff --git a/test/unitTest/actors/alice-bob_SIP.yml b/test/unitTest/actors/alice-bob_SIP.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9dc629e2b7e9c02cc20c769b1a5fd4693714e839
--- /dev/null
+++ b/test/unitTest/actors/alice-bob_SIP.yml
@@ -0,0 +1,19 @@
+default-account:
+    type: SIP
+    upnpEnabled: "true"
+    SRTP.keyExchange: "none"
+
+accounts:
+  alice:
+    displayName: ALICE
+    alias: ALICE
+    hostname: X.X.X.X
+    username: YYY
+    password: ZZZ
+
+  bob:
+    displayName: BOB
+    alias: BOB
+    hostname: X.X.X.X
+    username: AAA
+    password: BBB
diff --git a/test/unitTest/call/sipcall.cpp b/test/unitTest/call/sipcall.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5a971fa5328f1fda0798e10b9de0f4ad82d6e484
--- /dev/null
+++ b/test/unitTest/call/sipcall.cpp
@@ -0,0 +1,149 @@
+/*
+ *  Copyright (C) 2024 Savoir-faire Linux Inc.
+ *  Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "manager.h"
+#include "sip/sipaccount.h"
+#include "sip/sipcall.h"
+#include "sip/siptransport.h"
+#include "../../test_runner.h"
+#include "jami.h"
+#include "account_const.h"
+#include "media_const.h"
+#include "call_const.h"
+#include "common.h"
+
+#include <dhtnet/connectionmanager.h>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <condition_variable>
+#include <filesystem>
+#include <string>
+
+using namespace libjami::Account;
+using namespace libjami::Call::Details;
+using namespace std::literals::chrono_literals;
+
+namespace jami {
+namespace test {
+
+class SIPCallTest : public CppUnit::TestFixture
+{
+public:
+    SIPCallTest()
+    {
+        // Init daemon
+        libjami::init(
+            libjami::InitFlag(libjami::LIBJAMI_FLAG_DEBUG | libjami::LIBJAMI_FLAG_CONSOLE_LOG));
+        if (not Manager::instance().initialized)
+            CPPUNIT_ASSERT(libjami::start("jami-sample.yml"));
+    }
+    ~SIPCallTest() { libjami::fini(); }
+    static std::string name() { return "Call"; }
+    void setUp();
+    void tearDown();
+
+    std::string aliceId;
+    std::string bobId;
+
+private:
+    void testCall();
+
+    CPPUNIT_TEST_SUITE(SIPCallTest);
+    CPPUNIT_TEST(testCall);
+    CPPUNIT_TEST_SUITE_END();
+};
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(SIPCallTest, SIPCallTest::name());
+
+void
+SIPCallTest::setUp()
+{
+    auto actors = load_actors_and_wait_for_announcement("actors/alice-bob_SIP.yml");
+    aliceId = actors["alice"];
+    bobId = actors["bob"];
+    std::this_thread::sleep_for(10s);
+}
+
+void
+SIPCallTest::tearDown()
+{
+    wait_for_removal_of({aliceId, bobId});
+}
+
+void
+SIPCallTest::testCall()
+{
+    auto aliceAccount = Manager::instance().getAccount<SIPAccount>(aliceId);
+    auto bobAccount = Manager::instance().getAccount<SIPAccount>(bobId);
+    auto bobUri = bobAccount->getUsername();
+    JAMI_ERROR("@@@@@@@@@22 {}", bobUri);
+    auto aliceUri = aliceAccount->getUsername();
+
+    std::mutex mtx;
+    std::unique_lock<std::mutex> lk {mtx};
+    std::condition_variable cv;
+    std::map<std::string, std::shared_ptr<libjami::CallbackWrapperBase>> confHandlers;
+    std::atomic_bool callReceived {false};
+    std::atomic<int> callStopped {0};
+    // Watch signals
+    confHandlers.insert(libjami::exportable_callback<libjami::CallSignal::IncomingCallWithMedia>(
+        [&](const std::string&,
+            const std::string&,
+            const std::string&,
+            const std::vector<std::map<std::string, std::string>>&) {
+            callReceived = true;
+            cv.notify_one();
+        }));
+    confHandlers.insert(libjami::exportable_callback<libjami::CallSignal::StateChange>(
+        [&](const std::string&, const std::string&, const std::string& state, signed) {
+            if (state == "OVER") {
+                callStopped += 1;
+                if (callStopped == 2)
+                    cv.notify_one();
+            }
+        }));
+    libjami::registerSignalHandlers(confHandlers);
+
+    JAMI_INFO("Start call between alice and Bob");
+    std::vector<std::map<std::string, std::string>> mediaList;
+    std::map<std::string, std::string> mediaAttribute
+        = {{libjami::Media::MediaAttributeKey::MEDIA_TYPE,
+            libjami::Media::MediaAttributeValue::AUDIO},
+            {libjami::Media::MediaAttributeKey::ENABLED, TRUE_STR},
+            {libjami::Media::MediaAttributeKey::MUTED, FALSE_STR},
+            {libjami::Media::MediaAttributeKey::SOURCE, ""},
+            {libjami::Media::MediaAttributeKey::LABEL, "audio_0"}};
+    mediaList.emplace_back(mediaAttribute);
+
+    auto call = libjami::placeCallWithMedia(aliceId, bobUri, mediaList);
+
+    CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&] { return callReceived.load(); }));
+
+    JAMI_INFO("Stop call between alice and Bob");
+    callStopped = 0;
+    Manager::instance().hangupCall(aliceId, call);
+    CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&] { return callStopped == 2; }));
+}
+
+} // namespace test
+} // namespace jami
+
+RING_TEST_RUNNER(jami::test::SIPCallTest::name())
diff --git a/test/unitTest/common.cpp b/test/unitTest/common.cpp
index 181f2f3cf45e30e62f7592430ed18d50cfae494b..ab3aea681ca62dc6435b283544dc68c59bb7909a 100644
--- a/test/unitTest/common.cpp
+++ b/test/unitTest/common.cpp
@@ -58,13 +58,20 @@ wait_for_announcement_of(const std::vector<std::string> accountIDs,
                         continue;
                     }
 
-                    try {
-                        if ("true"
-                            != details.at(libjami::Account::VolatileProperties::DEVICE_ANNOUNCED)) {
+                    if (jami::Manager::instance().getAccount(accountID)->getAccountType() == "SIP") {
+                        auto daemonStatus = details.at(libjami::Account::ConfProperties::Registration::STATUS);
+                        if (daemonStatus != "REGISTERED") {
+                            continue;
+                        }
+                    } else {
+                        try {
+                            if ("true"
+                                != details.at(libjami::Account::VolatileProperties::DEVICE_ANNOUNCED)) {
+                                continue;
+                            }
+                        } catch (const std::out_of_range&) {
                             continue;
                         }
-                    } catch (const std::out_of_range&) {
-                        continue;
                     }
 
                     accountsReady[i] = true;
@@ -148,7 +155,6 @@ std::map<std::string, std::string>
 load_actors(const std::filesystem::path& from_yaml)
 {
     std::map<std::string, std::string> actors {};
-    std::map<std::string, std::string> default_details = libjami::getAccountTemplate("RING");
 
     std::ifstream file(from_yaml);
 
@@ -160,9 +166,15 @@ load_actors(const std::filesystem::path& from_yaml)
 
     auto default_account = node["default-account"];
 
+    std::map<std::string, std::string> default_details = libjami::getAccountTemplate(default_account["type"].as<std::string>());
     if (default_account.IsMap()) {
         for (const auto& kv : default_account) {
-            default_details["Account." + kv.first.as<std::string>()] = kv.second.as<std::string>();
+            auto key = kv.first.as<std::string>();
+            if (default_details.find(key) != default_details.end()) {
+                default_details[key] = kv.second.as<std::string>();
+            } else {
+                default_details["Account." + key] = kv.second.as<std::string>();
+            }
         }
     }
 
@@ -176,7 +188,12 @@ load_actors(const std::filesystem::path& from_yaml)
         auto details = std::map<std::string, std::string>(default_details);
 
         for (const auto& detail : account) {
-            details["Account." + detail.first.as<std::string>()] = detail.second.as<std::string>();
+            auto key = detail.first.as<std::string>();
+            if (details.find(key) != details.end()) {
+                details[key] = detail.second.as<std::string>();
+            } else {
+                details["Account." + key] = detail.second.as<std::string>();
+            }
         }
 
         actors[account_name] = jami::Manager::instance().addAccount(details);