From 921ebf9b92bb02fe8d598aa29b18f91005bc0154 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Sat, 14 May 2011 17:53:05 +0200
Subject: Ack pending stanzas on logout.

Resolves: #877

diff --git a/Swiften/Client/ClientSession.cpp b/Swiften/Client/ClientSession.cpp
index ed4e165..846a5e7 100644
--- a/Swiften/Client/ClientSession.cpp
+++ b/Swiften/Client/ClientSession.cpp
@@ -416,6 +416,9 @@ void ClientSession::finishSession(boost::shared_ptr<Swift::Error> error) {
 	state = Finishing;
 	error_ = error;
 	assert(stream->isOpen());
+	if (stanzaAckResponder_) {
+		stanzaAckResponder_->handleAckRequestReceived();
+	}
 	stream->writeFooter();
 	stream->close();
 }
diff --git a/Swiften/Client/UnitTest/ClientSessionTest.cpp b/Swiften/Client/UnitTest/ClientSessionTest.cpp
index 61223fb..25476c0 100644
--- a/Swiften/Client/UnitTest/ClientSessionTest.cpp
+++ b/Swiften/Client/UnitTest/ClientSessionTest.cpp
@@ -13,6 +13,7 @@
 
 #include <Swiften/Session/SessionStream.h>
 #include <Swiften/Client/ClientSession.h>
+#include <Swiften/Elements/Message.h>
 #include <Swiften/Elements/StartTLSRequest.h>
 #include <Swiften/Elements/StreamFeatures.h>
 #include <Swiften/Elements/StreamError.h>
@@ -23,6 +24,7 @@
 #include <Swiften/Elements/AuthFailure.h>
 #include <Swiften/Elements/StreamManagementEnabled.h>
 #include <Swiften/Elements/StreamManagementFailed.h>
+#include <Swiften/Elements/StanzaAck.h>
 #include <Swiften/Elements/EnableStreamManagement.h>
 #include <Swiften/Elements/IQ.h>
 #include <Swiften/Elements/ResourceBind.h>
@@ -45,6 +47,7 @@ class ClientSessionTest : public CppUnit::TestFixture {
 		CPPUNIT_TEST(testAuthenticate_NoValidAuthMechanisms);
 		CPPUNIT_TEST(testStreamManagement);
 		CPPUNIT_TEST(testStreamManagement_Failed);
+		CPPUNIT_TEST(testFinishAcksStanzas);
 		/*
 		CPPUNIT_TEST(testResourceBind);
 		CPPUNIT_TEST(testResourceBind_ChangeResource);
@@ -275,6 +278,17 @@ class ClientSessionTest : public CppUnit::TestFixture {
 			session->finish();
 		}
 
+		void testFinishAcksStanzas() {
+			boost::shared_ptr<ClientSession> session(createSession());
+			initializeSession(session);
+			server->sendMessage();
+			server->sendMessage();
+			server->sendMessage();
+
+			session->finish();
+
+			server->receiveAck(3);
+		}
 
 	private:
 		boost::shared_ptr<ClientSession> createSession() {
@@ -285,6 +299,23 @@ class ClientSessionTest : public CppUnit::TestFixture {
 			return session;
 		}
 
+		void initializeSession(boost::shared_ptr<ClientSession> session) {
+			session->start();
+			server->receiveStreamStart();
+			server->sendStreamStart();
+			server->sendStreamFeaturesWithPLAINAuthentication();
+			session->sendCredentials("mypass");
+			server->receiveAuthRequest("PLAIN");
+			server->sendAuthSuccess();
+			server->receiveStreamStart();
+			server->sendStreamStart();
+			server->sendStreamFeaturesWithBindAndStreamManagement();
+			server->receiveBind();
+			server->sendBindResult();
+			server->receiveStreamManagementEnable();
+			server->sendStreamManagementEnabled();
+		}
+
 		void handleSessionFinished(boost::shared_ptr<Error> error) {
 			sessionFinishedReceived = true;
 			sessionFinishedError = error;
@@ -447,6 +478,12 @@ class ClientSessionTest : public CppUnit::TestFixture {
 					onElementReceived(iq);
 				}
 
+				void sendMessage() {
+					boost::shared_ptr<Message> message = boost::make_shared<Message>();
+					message->setTo(JID("foo@bar.com/bla"));
+					onElementReceived(message);
+				}
+
 				void receiveStreamStart() {
 					Event event = popEvent();
 					CPPUNIT_ASSERT(event.header);
@@ -481,6 +518,14 @@ class ClientSessionTest : public CppUnit::TestFixture {
 					bindID = iq->getID();
 				}
 
+				void receiveAck(unsigned int n) {
+					Event event = popEvent();
+					CPPUNIT_ASSERT(event.element);
+					boost::shared_ptr<StanzaAck> ack = boost::dynamic_pointer_cast<StanzaAck>(event.element);
+					CPPUNIT_ASSERT(ack);
+					CPPUNIT_ASSERT_EQUAL(n, ack->getHandledStanzasCount());
+				}
+
 				Event popEvent() {
 					CPPUNIT_ASSERT(receivedEvents.size() > 0);
 					Event event = receivedEvents.front();
-- 
cgit v0.10.2-6-g49f6