diff --git a/tests/communication/test-sync-logic-handler.cpp b/tests/communication/test-sync-logic-handler.cpp
new file mode 100644
index 0000000..eba8064
--- /dev/null
+++ b/tests/communication/test-sync-logic-handler.cpp
@@ -0,0 +1,278 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2019,  The University of Memphis,
+ *                           Regents of the University of California,
+ *                           Arizona Board of Regents.
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR 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.
+ *
+ * NLSR 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
+ * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "communication/sync-logic-handler.hpp"
+#include "../test-common.hpp"
+#include "common.hpp"
+#include "nlsr.hpp"
+#include "lsa.hpp"
+
+#include <ndn-cxx/util/dummy-client-face.hpp>
+
+namespace nlsr {
+namespace test {
+
+using std::shared_ptr;
+
+template<int32_t Protocol>
+class SyncLogicFixture : public UnitTestTimeFixture
+{
+public:
+  SyncLogicFixture()
+    : face(m_ioService, m_keyChain)
+    , conf(face)
+    , confProcessor(conf, Protocol)
+    , testIsLsaNew([] (const ndn::Name& name, const Lsa::Type& lsaType,
+                       const uint64_t sequenceNumber) {
+                     return true;
+                   })
+    , sync(face, testIsLsaNew, conf)
+    , updateNamePrefix(this->conf.getLsaPrefix().toUri() +
+                       this->conf.getSiteName().toUri() +
+                       "/%C1.Router/other-router/")
+  {
+    addIdentity(conf.getRouterPrefix());
+  }
+
+  void
+  receiveUpdate(const std::string& prefix, uint64_t seqNo)
+  {
+    this->advanceClocks(ndn::time::milliseconds(1), 10);
+    face.sentInterests.clear();
+
+    if (Protocol == SYNC_PROTOCOL_CHRONOSYNC) {
+      std::vector<chronosync::MissingDataInfo> updates;
+      updates.push_back({ndn::Name(prefix).appendNumber(1), 0, seqNo});
+      sync.m_syncLogic->onChronoSyncUpdate(updates);
+    }
+    else {
+      std::vector<psync::MissingDataInfo> updates;
+      updates.push_back({ndn::Name(prefix), 0, seqNo});
+      sync.m_syncLogic->onPSyncUpdate(updates);
+    }
+
+    this->advanceClocks(ndn::time::milliseconds(1), 10);
+  }
+
+public:
+  ndn::util::DummyClientFace face;
+  ConfParameter conf;
+  DummyConfFileProcessor confProcessor;
+  SyncLogicHandler::IsLsaNew testIsLsaNew;
+  SyncLogicHandler sync;
+
+  const std::string updateNamePrefix;
+  const std::vector<Lsa::Type> lsaTypes = {Lsa::Type::NAME, Lsa::Type::ADJACENCY,
+                                             Lsa::Type::COORDINATE};
+};
+
+using mpl_::int_;
+using Protocols = boost::mpl::vector<int_<SYNC_PROTOCOL_CHRONOSYNC>,
+                                     int_<SYNC_PROTOCOL_PSYNC>>;
+
+BOOST_AUTO_TEST_SUITE(TestSyncLogicHandler)
+
+/* Tests that when SyncLogicHandler receives an LSA of either Name or
+   Adjacency type that appears to be newer, it will emit to its signal
+   with those LSA details.
+ */
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(UpdateForOtherLS, T, Protocols, SyncLogicFixture<T::value>)
+{
+  std::vector<Lsa::Type> lsaTypes = {Lsa::Type::NAME, Lsa::Type::ADJACENCY};
+
+  uint64_t syncSeqNo = 1;
+
+  for (const Lsa::Type& lsaType : lsaTypes) {
+    std::string updateName = this->updateNamePrefix + std::to_string(lsaType);
+
+    // Actual testing done here -- signal function callback
+    ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
+      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+        BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
+        BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
+      });
+
+    this->receiveUpdate(updateName, syncSeqNo);
+  }
+}
+
+/* Tests that when SyncLogicHandler in HR mode receives an LSA of
+   either Coordinate or Name type that appears to be newer, it will
+   emit to its signal with those LSA details.
+ */
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(UpdateForOtherHR, T, Protocols, SyncLogicFixture<T::value>)
+{
+  this->conf.setHyperbolicState(HYPERBOLIC_STATE_ON);
+
+  uint64_t syncSeqNo = 1;
+  std::vector<Lsa::Type> lsaTypes = {Lsa::Type::NAME, Lsa::Type::COORDINATE};
+
+  for (const Lsa::Type& lsaType : lsaTypes) {
+    std::string updateName = this->updateNamePrefix + std::to_string(lsaType);
+
+    ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
+      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+        BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
+        BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
+      });
+
+    this->receiveUpdate(updateName, syncSeqNo);
+  }
+}
+
+/* Tests that when SyncLogicHandler in HR-dry mode receives an LSA of
+   any type that appears to be newer, it will emit to its signal with
+   those LSA details.
+ */
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(UpdateForOtherHRDry, T, Protocols, SyncLogicFixture<T::value>)
+{
+  this->conf.setHyperbolicState(HYPERBOLIC_STATE_DRY_RUN);
+
+  uint64_t syncSeqNo = 1;
+
+  for (const Lsa::Type& lsaType : this->lsaTypes) {
+    std::string updateName = this->updateNamePrefix + std::to_string(lsaType);
+
+    ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
+      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+        BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
+        BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
+      });
+
+    this->receiveUpdate(updateName, syncSeqNo);
+  }
+}
+
+/* Tests that when SyncLogicHandler receives an update for an LSA with
+   details matching this router's details, it will *not* emit to its
+   signal those LSA details.
+ */
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(NoUpdateForSelf, T, Protocols, SyncLogicFixture<T::value>)
+{
+  const uint64_t sequenceNumber = 1;
+
+  for (const Lsa::Type& lsaType : this->lsaTypes) {
+    // To ensure that we get correctly-separated components, create
+    // and modify a Name to hand off.
+    ndn::Name updateName = ndn::Name{this->conf.getLsaPrefix()};
+    updateName.append(this->conf.getSiteName())
+              .append(this->conf.getRouterName())
+              .append(std::to_string(lsaType));
+
+    ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
+      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+        BOOST_FAIL("Updates for self should not be emitted!");
+      });
+
+    this->receiveUpdate(updateName.toUri(), sequenceNumber);
+  }
+}
+
+/* Tests that when SyncLogicHandler receives an update for an LSA with
+   details that do not match the expected format, it will *not* emit
+   to its signal those LSA details.
+ */
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(MalformedUpdate, T, Protocols, SyncLogicFixture<T::value>)
+{
+  const uint64_t sequenceNumber = 1;
+
+  for (const Lsa::Type& lsaType : this->lsaTypes) {
+    ndn::Name updateName{this->conf.getSiteName()};
+    updateName.append(this->conf.getRouterName()).append(std::to_string(lsaType));
+
+    ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
+      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+        BOOST_FAIL("Malformed updates should not be emitted!");
+      });
+
+    this->receiveUpdate(updateName.toUri(), sequenceNumber);
+  }
+}
+
+/* Tests that when SyncLogicHandler receives an update for an LSA with
+   details that do not appear to be new, it will *not* emit to its
+   signal those LSA details.
+ */
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(LsaNotNew, T, Protocols, SyncLogicFixture<T::value>)
+{
+  auto testLsaAlwaysFalse = [] (const ndn::Name& routerName, const Lsa::Type& lsaType,
+                                const uint64_t& sequenceNumber) {
+    return false;
+  };
+
+  const uint64_t sequenceNumber = 1;
+  SyncLogicHandler sync{this->face, testLsaAlwaysFalse, this->conf};
+    ndn::util::signal::ScopedConnection connection = sync.onNewLsa->connect(
+      [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+        BOOST_FAIL("An update for an LSA with non-new sequence number should not emit!");
+      });
+
+  std::string updateName = this->updateNamePrefix + std::to_string(Lsa::Type::NAME);
+
+  this->receiveUpdate(updateName, sequenceNumber);
+}
+
+/* Tests that SyncLogicHandler successfully concatenates configured
+   variables together to form the necessary prefixes to advertise
+   through ChronoSync.
+ */
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(UpdatePrefix, T, Protocols, SyncLogicFixture<T::value>)
+{
+  ndn::Name expectedPrefix = this->conf.getLsaPrefix();
+  expectedPrefix.append(this->conf.getSiteName());
+  expectedPrefix.append(this->conf.getRouterName());
+
+  this->sync.buildUpdatePrefix();
+
+  BOOST_CHECK_EQUAL(this->sync.m_nameLsaUserPrefix,
+                    ndn::Name(expectedPrefix).append(std::to_string(Lsa::Type::NAME)));
+  BOOST_CHECK_EQUAL(this->sync.m_adjLsaUserPrefix,
+                    ndn::Name(expectedPrefix).append(std::to_string(Lsa::Type::ADJACENCY)));
+  BOOST_CHECK_EQUAL(this->sync.m_coorLsaUserPrefix,
+                    ndn::Name(expectedPrefix).append(std::to_string(Lsa::Type::COORDINATE)));
+}
+
+/* Tests that SyncLogicHandler's socket will be created when
+   Nlsr is initialized, preventing use of sync before the
+   socket is created.
+
+   NB: This test is as much an Nlsr class test as a
+   SyncLogicHandler class test, but it rides the line and ends up here.
+ */
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(createSyncLogicOnInitialization, T, Protocols,
+                                 SyncLogicFixture<T::value>) // Bug #2649
+{
+  Nlsr nlsr(this->face, this->m_keyChain, this->conf);
+
+  // Make sure an adjacency LSA has not been built yet
+  ndn::Name key = ndn::Name(this->conf.getRouterPrefix()).append(std::to_string(Lsa::Type::ADJACENCY));
+  AdjLsa* lsa = nlsr.m_lsdb.findAdjLsa(key);
+  BOOST_REQUIRE(lsa == nullptr);
+
+  // Publish a routing update before an Adjacency LSA is built
+  BOOST_CHECK_NO_THROW(nlsr.m_lsdb.getSyncLogicHandler()
+                       .publishRoutingUpdate(Lsa::Type::ADJACENCY, 0));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace test
+} // namespace nlsr
