From 336aa7d1c0a5aa223a6543d50ee17d82560c2b84 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Fri, 31 Jul 2009 23:26:33 +0200
Subject: Added LinkLocalConnectorTest.


diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp
index 5079192..0ba4dbb 100644
--- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp
+++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp
@@ -47,6 +47,22 @@ void FakeDNSSDQuerier::addRunningQuery(boost::shared_ptr<FakeDNSSDQuery> query)
 		DNSSDServiceID service(registerQuery->name, domain);
 		MainEventLoop::postEvent(boost::bind(boost::ref(registerQuery->onRegisterFinished), service), shared_from_this());
 	}
+	else if (boost::shared_ptr<FakeDNSSDResolveHostnameQuery> resolveHostnameQuery = boost::dynamic_pointer_cast<FakeDNSSDResolveHostnameQuery>(query)) {
+		std::map<String,HostAddress>::const_iterator i = addresses.find(resolveHostnameQuery->hostname);
+		if (i != addresses.end()) {
+			MainEventLoop::postEvent(
+					boost::bind(
+						boost::ref(resolveHostnameQuery->onHostnameResolved), i->second), 
+					shared_from_this());
+		}
+		else {
+			MainEventLoop::postEvent(
+					boost::bind(
+						boost::ref(resolveHostnameQuery->onHostnameResolved), 
+						boost::optional<HostAddress>()), 
+					shared_from_this());
+		}
+	}
 }
 
 void FakeDNSSDQuerier::removeRunningQuery(boost::shared_ptr<FakeDNSSDQuery> query) {
@@ -102,4 +118,8 @@ void FakeDNSSDQuerier::setRegisterError() {
 	}
 }
 
+void FakeDNSSDQuerier::setAddress(const String& hostname, const HostAddress& address) {
+	addresses[hostname] = address;
+}
+
 }
diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h
index f2ec17b..94d4074 100644
--- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h
+++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h
@@ -6,9 +6,11 @@
 #include <set>
 
 #include "Swiften/Base/foreach.h"
+#include "Swiften/Base/String.h"
 #include "Swiften/EventLoop/EventOwner.h"
 #include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h"
 #include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h"
+#include "Swiften/Network/HostAddress.h"
 
 namespace Swift {
 	class ByteArray;
@@ -37,6 +39,7 @@ namespace Swift {
 			void removeService(const DNSSDServiceID& id);
 			void setServiceInfo(const DNSSDServiceID& id, const DNSSDResolveServiceQuery::Result& info);
 			bool isServiceRegistered(const String& name, int port, const ByteArray& info);
+			void setAddress(const String& hostname, const HostAddress& address);
 
 			void setBrowseError();
 			void setRegisterError();
@@ -59,5 +62,6 @@ namespace Swift {
 			std::set<DNSSDServiceID> services;
 			typedef std::map<DNSSDServiceID,DNSSDResolveServiceQuery::Result> ServiceInfoMap;
 			ServiceInfoMap serviceInfo;
+			std::map<String, HostAddress> addresses;
 	};
 }
diff --git a/Swiften/LinkLocal/LinkLocalConnector.cpp b/Swiften/LinkLocal/LinkLocalConnector.cpp
index 18b5d6a..13d57e8 100644
--- a/Swiften/LinkLocal/LinkLocalConnector.cpp
+++ b/Swiften/LinkLocal/LinkLocalConnector.cpp
@@ -44,7 +44,7 @@ void LinkLocalConnector::handleHostnameResolved(const boost::optional<HostAddres
 		connection->connect(HostAddressPort(*address, port));
 	}
 	else {
-		onConnectFinished(false);
+		onConnectFinished(true);
 	}
 }
 
diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalConnectorTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalConnectorTest.cpp
new file mode 100644
index 0000000..1b9b0aa
--- /dev/null
+++ b/Swiften/LinkLocal/UnitTest/LinkLocalConnectorTest.cpp
@@ -0,0 +1,97 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/LinkLocal/LinkLocalConnector.h"
+#include "Swiften/LinkLocal/LinkLocalService.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h"
+#include "Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h"
+#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h"
+#include "Swiften/EventLoop/DummyEventLoop.h"
+#include "Swiften/Network/FakeConnection.h"
+
+using namespace Swift;
+
+class LinkLocalConnectorTest : public CppUnit::TestFixture {
+		CPPUNIT_TEST_SUITE(LinkLocalConnectorTest);
+		CPPUNIT_TEST(testConnect);
+		CPPUNIT_TEST(testConnect_UnableToResolve);
+		CPPUNIT_TEST(testConnect_UnableToConnect);
+		CPPUNIT_TEST_SUITE_END();
+
+	public:
+		void setUp() {
+			eventLoop = new DummyEventLoop();
+			querier = boost::shared_ptr<FakeDNSSDQuerier>(
+					new FakeDNSSDQuerier("rabbithole.local"));
+			connection = boost::shared_ptr<FakeConnection>(new FakeConnection());
+			connectFinished = false;
+		}
+
+		void tearDown() {
+			delete eventLoop;
+		}
+
+		void testConnect() {
+			boost::shared_ptr<LinkLocalConnector> 
+					testling(createConnector("rabbithole.local", 1234));
+			querier->setAddress("rabbithole.local", HostAddress("192.168.1.1"));
+
+			testling->connect();
+			eventLoop->processEvents();
+
+			CPPUNIT_ASSERT(connectFinished);
+			CPPUNIT_ASSERT(!connectError);
+			CPPUNIT_ASSERT(connection->connectedTo);
+			CPPUNIT_ASSERT_EQUAL(String(connection->connectedTo->getAddress().toString()), String("192.168.1.1"));
+			CPPUNIT_ASSERT_EQUAL(connection->connectedTo->getPort(), 1234);
+		}
+
+		void testConnect_UnableToResolve() {
+			boost::shared_ptr<LinkLocalConnector> 
+					testling(createConnector("rabbithole.local", 1234));
+
+			testling->connect();
+			eventLoop->processEvents();
+
+			CPPUNIT_ASSERT(connectFinished);
+			CPPUNIT_ASSERT(connectError);
+			CPPUNIT_ASSERT(!connection->connectedTo);
+		}
+
+		void testConnect_UnableToConnect() {
+			boost::shared_ptr<LinkLocalConnector> 
+					testling(createConnector("rabbithole.local", 1234));
+			querier->setAddress("rabbithole.local", HostAddress("192.168.1.1"));
+			connection->setError(Connection::ReadError);
+
+			testling->connect();
+			eventLoop->processEvents();
+
+			CPPUNIT_ASSERT(connectFinished);
+			CPPUNIT_ASSERT(connectError);
+			CPPUNIT_ASSERT(!connection->connectedTo);
+		}
+	
+	private:
+		boost::shared_ptr<LinkLocalConnector> createConnector(const String& hostname, int port) {
+			boost::shared_ptr<LinkLocalConnector> result(new LinkLocalConnector(
+					JID("rabbit@teaparty"), hostname, 0, port, querier, connection));
+			result->onConnectFinished.connect(
+					boost::bind(&LinkLocalConnectorTest::handleConnected, this, _1));
+			return result;
+		}
+
+		void handleConnected(bool e) {
+			connectFinished = true;
+			connectError = e;
+		}
+	
+	private:
+		DummyEventLoop* eventLoop;
+		boost::shared_ptr<FakeDNSSDQuerier> querier;
+		boost::shared_ptr<FakeConnection> connection;
+		bool connectFinished;
+		bool connectError;
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(LinkLocalConnectorTest);
diff --git a/Swiften/LinkLocal/UnitTest/Makefile.inc b/Swiften/LinkLocal/UnitTest/Makefile.inc
index e5f1bf0..330808a 100644
--- a/Swiften/LinkLocal/UnitTest/Makefile.inc
+++ b/Swiften/LinkLocal/UnitTest/Makefile.inc
@@ -1,4 +1,5 @@
 UNITTEST_SOURCES += \
 	Swiften/LinkLocal/UnitTest/LinkLocalServiceTest.cpp \
 	Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp \
-	Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp
+	Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp \
+	Swiften/LinkLocal/UnitTest/LinkLocalConnectorTest.cpp
diff --git a/Swiften/Network/FakeConnection.h b/Swiften/Network/FakeConnection.h
new file mode 100644
index 0000000..076a1f1
--- /dev/null
+++ b/Swiften/Network/FakeConnection.h
@@ -0,0 +1,57 @@
+#pragma once
+
+#include <boost/optional.hpp>
+#include <boost/bind.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <vector>
+
+#include "Swiften/Network/Connection.h"
+#include "Swiften/Network/HostAddressPort.h"
+#include "Swiften/EventLoop/EventOwner.h"
+#include "Swiften/EventLoop/MainEventLoop.h"
+
+namespace Swift {
+	class FakeConnection : 
+			public Connection, 
+			public EventOwner,
+			public boost::enable_shared_from_this<FakeConnection> {
+		public:
+			FakeConnection() {}
+
+			virtual void listen() {
+				assert(false);
+			}
+
+			void setError(const Error& e) {
+				error = boost::optional<Error>(e);
+				if (connectedTo) {
+					MainEventLoop::postEvent(
+							boost::bind(boost::ref(onDisconnected), error),
+							shared_from_this());
+				}
+			}
+
+			virtual void connect(const HostAddressPort& address) {
+				if (!error) {
+					connectedTo = address;
+				}
+				MainEventLoop::postEvent(
+						boost::bind(boost::ref(onConnectFinished), error),
+						shared_from_this());
+			}
+
+			virtual void disconnect() {
+				MainEventLoop::postEvent(
+						boost::bind(boost::ref(onDisconnected), error),
+						shared_from_this());
+			}
+
+			virtual void write(const ByteArray& data) {
+				dataWritten.push_back(data);
+			}
+
+			boost::optional<HostAddressPort> connectedTo;
+			std::vector<ByteArray> dataWritten;
+			boost::optional<Error> error;
+	};
+}
-- 
cgit v0.10.2-6-g49f6