From c9ab4b6c41eef3ccfe6627f62e7bc085c6743a41 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Sun, 5 Sep 2010 13:29:34 +0200
Subject: Clear VCardUpdateManager's cache upon login.

Resolves: #554

diff --git a/Swiften/Avatars/UnitTest/VCardUpdateAvatarManagerTest.cpp b/Swiften/Avatars/UnitTest/VCardUpdateAvatarManagerTest.cpp
index e3d9c58..ce100ee 100644
--- a/Swiften/Avatars/UnitTest/VCardUpdateAvatarManagerTest.cpp
+++ b/Swiften/Avatars/UnitTest/VCardUpdateAvatarManagerTest.cpp
@@ -27,22 +27,14 @@ class VCardUpdateAvatarManagerTest : public CppUnit::TestFixture {
 		CPPUNIT_TEST(testUpdate_NewHashStoresAvatarAndEmitsNotificationOnVCardReceive);
 		CPPUNIT_TEST(testUpdate_KnownHash);
 		CPPUNIT_TEST(testUpdate_KnownHashFromDifferentUserDoesNotRequestVCardButTriggersNotification);
-		/*&
-		CPPUNIT_TEST(testUpdate_UpdateNewHashAlreadyHaveAvatar);
-		CPPUNIT_TEST(testUpdate_UpdateNewHashFromMUC);
-		CPPUNIT_TEST(testUpdate_UpdateSameHash);*/
-		//CPPUNIT_TEST(testUpdate_UpdateWithError);
-		/*
-		CPPUNIT_TEST(testUpdate_UpdateNewHashSameThanOtherUser);
-		CPPUNIT_TEST(testReceiveVCard);
-		CPPUNIT_TEST(testGetAvatarPath);
-		CPPUNIT_TEST(testGetAvatarPathFromMUC);*/
+		CPPUNIT_TEST(testStanzaChannelReset);
 		CPPUNIT_TEST_SUITE_END();
 
 	public:
 		void setUp() {
 			ownJID = JID("foo@fum.com/bum");
 			stanzaChannel = new DummyStanzaChannel();
+			stanzaChannel->setAvailable(true);
 			iqRouter = new IQRouter(stanzaChannel);
 			mucRegistry = new DummyMUCRegistry();
 			avatarStorage = new AvatarMemoryStorage();
@@ -111,22 +103,21 @@ class VCardUpdateAvatarManagerTest : public CppUnit::TestFixture {
 			CPPUNIT_ASSERT_EQUAL(avatar1Hash, changes[0].second);
 		}
 
-/*
-		void testUpdate_UpdateNewHashFromMUC() {
+		void testStanzaChannelReset() {
 			std::auto_ptr<VCardUpdateAvatarManager> testling = createManager();
-		}
-
-		*/
-
-		/*void testUpdate_UpdateWithError() {
-			std::auto_ptr<VCardUpdateAvatarManager> testling = createManager();
-			boost::shared_ptr<Presence> update = createPresenceWithPhotoHash();
-			update->addPayload(boost::shared_ptr<ErrorPayload>(new ErrorPayload()));
-			stanzaChannel_->onPresenceReceived(update);
+			stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash));
+			stanzaChannel->onIQReceived(createVCardResult(avatar1));
+			changes.clear();
+			stanzaChannel->sentStanzas.clear();
 
-			CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(stanzaChannel_->sentStanzas.size()));
-		}*/
+			stanzaChannel->setAvailable(false);
+			stanzaChannel->setAvailable(true);
+			stanzaChannel->onPresenceReceived(createPresenceWithPhotoHash(user1, avatar1Hash));
 
+			CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(changes.size()));
+			CPPUNIT_ASSERT_EQUAL(user1.toBare(), changes[0].first);
+			CPPUNIT_ASSERT_EQUAL(avatar1Hash, changes[0].second);
+		}
 
 	private:
 		std::auto_ptr<VCardUpdateAvatarManager> createManager() {
diff --git a/Swiften/Avatars/VCardUpdateAvatarManager.cpp b/Swiften/Avatars/VCardUpdateAvatarManager.cpp
index 80d7730..dbc0b9b 100644
--- a/Swiften/Avatars/VCardUpdateAvatarManager.cpp
+++ b/Swiften/Avatars/VCardUpdateAvatarManager.cpp
@@ -21,6 +21,7 @@ namespace Swift {
 
 VCardUpdateAvatarManager::VCardUpdateAvatarManager(VCardManager* vcardManager, StanzaChannel* stanzaChannel, AvatarStorage* avatarStorage, MUCRegistry* mucRegistry) : vcardManager_(vcardManager), stanzaChannel_(stanzaChannel), avatarStorage_(avatarStorage), mucRegistry_(mucRegistry) {
 	stanzaChannel->onPresenceReceived.connect(boost::bind(&VCardUpdateAvatarManager::handlePresenceReceived, this, _1));
+	stanzaChannel->onAvailableChanged.connect(boost::bind(&VCardUpdateAvatarManager::handleStanzaChannelAvailableChanged, this, _1));
 	vcardManager_->onVCardChanged.connect(boost::bind(&VCardUpdateAvatarManager::handleVCardChanged, this, _1, _2));
 }
 
@@ -92,5 +93,11 @@ JID VCardUpdateAvatarManager::getAvatarJID(const JID& jid) const {
 	return (mucRegistry_ && mucRegistry_->isMUC(bareFrom)) ? jid : bareFrom;
 }
 
+void VCardUpdateAvatarManager::handleStanzaChannelAvailableChanged(bool available) {
+	if (available) {
+		avatarHashes_.clear();
+	}
+}
+
 
 }
diff --git a/Swiften/Avatars/VCardUpdateAvatarManager.h b/Swiften/Avatars/VCardUpdateAvatarManager.h
index 16c0ca3..e29db1c 100644
--- a/Swiften/Avatars/VCardUpdateAvatarManager.h
+++ b/Swiften/Avatars/VCardUpdateAvatarManager.h
@@ -35,6 +35,7 @@ namespace Swift {
 
 		private:
 			void handlePresenceReceived(boost::shared_ptr<Presence>);
+			void handleStanzaChannelAvailableChanged(bool);
 			void handleVCardChanged(const JID& from, VCard::ref);
 			void setAvatarHash(const JID& from, const String& hash);
 			JID getAvatarJID(const JID& o) const;
diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp
index 2406b0f..bf651cc 100644
--- a/Swiften/Client/Client.cpp
+++ b/Swiften/Client/Client.cpp
@@ -37,7 +37,7 @@ Client::~Client() {
 }
 
 bool Client::isAvailable() {
-	return session_;
+	return session_ && session_->getState() == ClientSession::Initialized;
 }
 
 void Client::connect() {
@@ -80,7 +80,7 @@ void Client::handleConnectorFinished(boost::shared_ptr<Connection> connection, C
 		sessionStream_->initialize();
 
 		session_ = ClientSession::create(jid_, sessionStream_);
-		session_->onInitialized.connect(boost::bind(boost::ref(onConnected)));
+		session_->onInitialized.connect(boost::bind(&Client::handleSessionInitialized, this));
 		session_->onStanzaAcked.connect(boost::bind(&Client::handleStanzaAcked, this, _1));
 		session_->onFinished.connect(boost::bind(&Client::handleSessionFinished, this, _1));
 		session_->onNeedCredentials.connect(boost::bind(&Client::handleNeedCredentials, this));
@@ -162,6 +162,7 @@ void Client::setCertificate(const String& certificate) {
 void Client::handleSessionFinished(boost::shared_ptr<Error> error) {
 	session_.reset();
 	closeConnection();
+	onAvailableChanged(false);
 	if (error) {
 		ClientError clientError;
 		if (boost::shared_ptr<ClientSession::Error> actualError = boost::dynamic_pointer_cast<ClientSession::Error>(error)) {
@@ -242,4 +243,9 @@ void Client::handleStanzaAcked(boost::shared_ptr<Stanza> stanza) {
 	onStanzaAcked(stanza);
 }
 
+void Client::handleSessionInitialized() {
+	onConnected();
+	onAvailableChanged(true);
+}
+
 }
diff --git a/Swiften/Client/Client.h b/Swiften/Client/Client.h
index 57228ef..1023108 100644
--- a/Swiften/Client/Client.h
+++ b/Swiften/Client/Client.h
@@ -58,6 +58,7 @@ namespace Swift {
 
 		private:
 			void handleConnectorFinished(boost::shared_ptr<Connection>, Connector::ref);
+			void handleSessionInitialized();
 			void send(boost::shared_ptr<Stanza>);
 			virtual String getNewIQID();
 			void handleStanza(boost::shared_ptr<Stanza>);
diff --git a/Swiften/Client/DummyStanzaChannel.h b/Swiften/Client/DummyStanzaChannel.h
index d43d68a..05066a8 100644
--- a/Swiften/Client/DummyStanzaChannel.h
+++ b/Swiften/Client/DummyStanzaChannel.h
@@ -13,12 +13,17 @@
 namespace Swift {
 	class DummyStanzaChannel : public StanzaChannel {
 		public:
-			DummyStanzaChannel() {}
+			DummyStanzaChannel() : available_(true) {}
 
 			virtual void sendStanza(boost::shared_ptr<Stanza> stanza) {
 				sentStanzas.push_back(stanza);
 			}
 
+			void setAvailable(bool available) {
+				available_ = available;
+				onAvailableChanged(available);
+			}
+
 			virtual void sendIQ(boost::shared_ptr<IQ> iq) {
 				sentStanzas.push_back(iq);
 			}
@@ -36,7 +41,7 @@ namespace Swift {
 			}
 			
 			virtual bool isAvailable() {
-				return true;
+				return available_;
 			}
 
 			virtual bool getStreamManagementEnabled() const {
@@ -49,5 +54,6 @@ namespace Swift {
 			}
 
 			std::vector<boost::shared_ptr<Stanza> > sentStanzas;
+			bool available_;
 	};
 }
diff --git a/Swiften/Client/StanzaChannel.h b/Swiften/Client/StanzaChannel.h
index 09a6db3..f7bb26a 100644
--- a/Swiften/Client/StanzaChannel.h
+++ b/Swiften/Client/StanzaChannel.h
@@ -21,6 +21,7 @@ namespace Swift {
 			virtual bool isAvailable() = 0;
 			virtual bool getStreamManagementEnabled() const = 0;
 
+			boost::signal<void (bool /* isAvailable */)> onAvailableChanged;
 			boost::signal<void (boost::shared_ptr<Message>)> onMessageReceived;
 			boost::signal<void (boost::shared_ptr<Presence>) > onPresenceReceived;
 			boost::signal<void (boost::shared_ptr<Stanza>)> onStanzaAcked;
-- 
cgit v0.10.2-6-g49f6