face: send Nack after every InterestCallback has responded

refs #4228

Change-Id: I3b1ef58c70d34c2099249216a3600efe01b79f71
diff --git a/tests/unit-tests/face.t.cpp b/tests/unit-tests/face.t.cpp
index e5f1d47..73c7347 100644
--- a/tests/unit-tests/face.t.cpp
+++ b/tests/unit-tests/face.t.cpp
@@ -327,6 +327,9 @@
 
 BOOST_AUTO_TEST_CASE(PutNack)
 {
+  face.setInterestFilter("/", bind([]{})); // register one Interest destination so that face can accept Nacks
+  advanceClocks(time::milliseconds(10));
+
   BOOST_CHECK_EQUAL(face.sentNacks.size(), 0);
 
   face.put(makeNack("/unsolicited", 18645250, lp::NackReason::NO_ROUTE));
@@ -352,6 +355,28 @@
   BOOST_CHECK(face.sentNacks[1].getTag<lp::CongestionMarkTag>() != nullptr);
 }
 
+BOOST_AUTO_TEST_CASE(PutMultipleNack)
+{
+  face.setInterestFilter("/", bind([]{}));
+  face.setInterestFilter("/", bind([]{})); // register two Interest destinations
+  advanceClocks(time::milliseconds(10));
+
+  face.receive(*makeInterest("/A", 14333271));
+  advanceClocks(time::milliseconds(10));
+
+  face.put(makeNack("/A", 14333271, lp::NackReason::CONGESTION)); // Nack from first destination
+  advanceClocks(time::milliseconds(10));
+  BOOST_CHECK_EQUAL(face.sentNacks.size(), 0); // should wait for Nacks from all destinations
+
+  face.put(makeNack("/A", 14333271, lp::NackReason::NO_ROUTE)); // Nack from second destination
+  advanceClocks(time::milliseconds(10));
+  BOOST_CHECK_EQUAL(face.sentNacks.size(), 1); // both destinations Nacked
+  BOOST_CHECK_EQUAL(face.sentNacks.at(0).getReason(), lp::NackReason::CONGESTION); // least severe reason
+
+  face.put(makeNack("/A", 14333271, lp::NackReason::DUPLICATE));
+  BOOST_CHECK_EQUAL(face.sentNacks.size(), 1); // additional Nacks are ignored
+}
+
 BOOST_AUTO_TEST_CASE(SetUnsetInterestFilter)
 {
   size_t nInterests = 0;
diff --git a/tests/unit-tests/lp/nack-header.t.cpp b/tests/unit-tests/lp/nack-header.t.cpp
index 83c9f9d..2140f81 100644
--- a/tests/unit-tests/lp/nack-header.t.cpp
+++ b/tests/unit-tests/lp/nack-header.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -32,6 +32,18 @@
 BOOST_AUTO_TEST_SUITE(Lp)
 BOOST_AUTO_TEST_SUITE(TestNackHeader)
 
+BOOST_AUTO_TEST_CASE(IsLessSevere)
+{
+  BOOST_CHECK_EQUAL(isLessSevere(NackReason::NONE, NackReason::NONE), false);
+  BOOST_CHECK_EQUAL(isLessSevere(NackReason::CONGESTION, NackReason::CONGESTION), false);
+
+  BOOST_CHECK_EQUAL(isLessSevere(NackReason::CONGESTION, NackReason::NONE), true);
+  BOOST_CHECK_EQUAL(isLessSevere(NackReason::NONE, NackReason::CONGESTION), false);
+
+  BOOST_CHECK_EQUAL(isLessSevere(NackReason::CONGESTION, NackReason::NO_ROUTE), true);
+  BOOST_CHECK_EQUAL(isLessSevere(NackReason::NO_ROUTE, NackReason::CONGESTION), false);
+}
+
 BOOST_AUTO_TEST_CASE(Encode)
 {
   NackHeader header;