From 36fafeec1cd35f5950d45f352dbfded77d91dc36 Mon Sep 17 00:00:00 2001
From: Don Gagne <don@thegagnes.com>
Date: Sat, 28 Dec 2013 13:43:48 -0800
Subject: [PATCH] Mock implementations of UAS, UASManager and QGCUASParamManger

Used for unit testing
---
 qgroundcontrol.pro                        |  16 ++-
 src/qgcunittest/MockQGCUASParamManager.cc |  25 +++++
 src/qgcunittest/MockQGCUASParamManager.h  |  78 +++++++++++++++
 src/qgcunittest/MockUAS.cc                |  21 ++++
 src/qgcunittest/MockUAS.h                 | 161 ++++++++++++++++++++++++++++++
 src/qgcunittest/MockUASManager.cc         |  34 +++++++
 src/qgcunittest/MockUASManager.h          | 101 +++++++++++++++++++
 7 files changed, 432 insertions(+), 4 deletions(-)
 create mode 100644 src/qgcunittest/MockQGCUASParamManager.cc
 create mode 100644 src/qgcunittest/MockQGCUASParamManager.h
 create mode 100644 src/qgcunittest/MockUAS.cc
 create mode 100644 src/qgcunittest/MockUAS.h
 create mode 100644 src/qgcunittest/MockUASManager.cc
 create mode 100644 src/qgcunittest/MockUASManager.h

diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro
index 54e2d7f..abaa633 100644
--- a/qgroundcontrol.pro
+++ b/qgroundcontrol.pro
@@ -511,7 +511,9 @@ HEADERS += src/MG.h \
     src/ui/px4_configuration/QGCPX4MulticopterConfig.h \
     src/ui/px4_configuration/QGCPX4SensorCalibration.h \
     src/ui/designer/QGCXYPlot.h \
-    src/ui/menuactionhelper.h
+    src/ui/menuactionhelper.h \
+    src/uas/UASManagerInterface.h \
+    src/uas/QGCUASParamManagerInterface.h
 
 # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler
 macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h
@@ -737,7 +739,7 @@ SOURCES += \
     src/ui/px4_configuration/QGCPX4SensorCalibration.cc \
     src/ui/designer/QGCXYPlot.cc \
     src/ui/menuactionhelper.cpp
-
+    
 CONFIG(debug, debug|release) {
     # Unit Test sources/headers go here
     
@@ -746,10 +748,16 @@ CONFIG(debug, debug|release) {
 
     HEADERS += \
         src/qgcunittest/AutoTest.h \
-        src/qgcunittest/UASUnitTest.h
+        src/qgcunittest/UASUnitTest.h \
+        src/qgcunittest/MockUASManager.h \
+        src/qgcunittest/MockUAS.h \
+        src/qgcunittest/MockQGCUASParamManager.h
 
     SOURCES += \
-        src/qgcunittest/UASUnitTest.cc
+        src/qgcunittest/UASUnitTest.cc \
+        src/qgcunittest/MockUASManager.cc \
+        src/qgcunittest/MockUAS.cc \
+        src/qgcunittest/MockQGCUASParamManager.cc 
 }
 
 # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler
diff --git a/src/qgcunittest/MockQGCUASParamManager.cc b/src/qgcunittest/MockQGCUASParamManager.cc
new file mode 100644
index 0000000..706d12a
--- /dev/null
+++ b/src/qgcunittest/MockQGCUASParamManager.cc
@@ -0,0 +1,25 @@
+#include "MockQGCUASParamManager.h"
+#include <QTest>
+#include <QDebug>
+
+MockQGCUASParamManager::MockQGCUASParamManager(void)
+{
+    
+}
+
+bool MockQGCUASParamManager::getParameterValue(int component, const QString& parameter, QVariant& value) const
+{
+    Q_UNUSED(component);
+    
+    if (_mapParams.contains(parameter)) {
+        value = _mapParams[parameter];
+    }
+    return false;
+}
+
+void MockQGCUASParamManager::setParameter(int component, QString parameterName, QVariant value)
+{
+    Q_UNUSED(component);
+
+    _mapParamsSet[parameterName] = value;
+}
diff --git a/src/qgcunittest/MockQGCUASParamManager.h b/src/qgcunittest/MockQGCUASParamManager.h
new file mode 100644
index 0000000..56b213c
--- /dev/null
+++ b/src/qgcunittest/MockQGCUASParamManager.h
@@ -0,0 +1,78 @@
+#ifndef MOCKQGCUASPARAMMANAGER_H
+#define MOCKQGCUASPARAMMANAGER_H
+
+#include "QGCUASParamManagerInterface.h"
+
+/// @file
+///     @brief This is a mock implementation of QGCUASParamManager for writing Unit Tests.
+///
+///     @author Don Gagne <don@thegagnes.com>
+
+
+class MockQGCUASParamManager : public QGCUASParamManagerInterface
+{
+    Q_OBJECT
+    
+signals:
+    // The following QGCSUASParamManagerInterface signals are supported
+    // currently none
+    
+public:
+    // Implemented QGCSUASParamManager overrides
+    virtual bool getParameterValue(int component, const QString& parameter, QVariant& value) const;
+    virtual int getDefaultComponentId(void) { return 0; }
+    virtual int countOnboardParams(void) { return _mapParams.count(); }
+    
+    public slots:
+    // Implemented QGCSUASParamManager overrides
+    void setParameter(int component, QString parameterName, QVariant value);
+    
+public:
+    // MockQGCUASParamManager methods
+    MockQGCUASParamManager(void);
+    
+    /// QMap of parameters, QString key is paremeter name, QVariant value is parameter value
+    typedef QMap<QString, QVariant> ParamMap_t;
+    
+    /// Sets current set of parameters to support calls like getParameterValue
+    void setMockParameters(ParamMap_t& map) { _mapParams = map; }
+    
+    /// Returns the parameters which were set by calls to setParameter calls
+    ParamMap_t getMockSetParameters(void) { return _mapParamsSet; }
+    /// Clears the set of parameters set by setParameter calls
+    void clearMockSetParameters(void) { _mapParamsSet.clear(); }
+    
+public:
+    // Unimplemented QGCUASParamManagerInterface overrides
+    virtual QList<int> getComponentForParam(const QString& parameter) const { Q_ASSERT(false); Q_UNUSED(parameter); return _bogusQListInt; }
+    virtual void setParamDescriptions(const QMap<QString,QString>& paramDescs) { Q_ASSERT(false); Q_UNUSED(paramDescs); }
+    virtual int countPendingParams() { Q_ASSERT(false); return 0; }
+    virtual UASParameterDataModel* dataModel() { Q_ASSERT(false); return NULL; }
+    
+public slots:
+    // Unimplemented QGCUASParamManagerInterface overrides
+    virtual void sendPendingParameters(bool persistAfterSend = false, bool forceSend = false)
+        { Q_ASSERT(false); Q_UNUSED(persistAfterSend); Q_UNUSED(forceSend); }
+    virtual void requestParameterList() { Q_ASSERT(false); }
+    virtual void requestParameterListIfEmpty() { Q_ASSERT(false); }
+    virtual void setPendingParam(int componentId,  const QString& key,  const QVariant& value, bool forceSend = false)
+        { Q_ASSERT(false); Q_UNUSED(componentId); Q_UNUSED(key); Q_UNUSED(value); Q_UNUSED(forceSend); }
+    virtual void clearAllPendingParams() { Q_ASSERT(false); }
+    virtual void requestParameterUpdate(int component, const QString& parameter)
+        { Q_ASSERT(false); Q_UNUSED(component); Q_UNUSED(parameter); }
+    virtual void writeOnboardParamsToStream(QTextStream &stream, const QString& uasName)
+        { Q_ASSERT(false); Q_UNUSED(stream); Q_UNUSED(uasName); }
+    virtual void readPendingParamsFromStream(QTextStream &stream) { Q_ASSERT(false); Q_UNUSED(stream); }
+    virtual void requestRcCalibrationParamsUpdate() { Q_ASSERT(false); }
+    virtual void copyVolatileParamsToPersistent() { Q_ASSERT(false); }
+    virtual void copyPersistentParamsToVolatile() { Q_ASSERT(false); }
+    
+private:
+    ParamMap_t          _mapParams;
+    ParamMap_t          _mapParamsSet;
+
+    // Bogus variables used for return types of NYI methods
+    QList<int>          _bogusQListInt;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/qgcunittest/MockUAS.cc b/src/qgcunittest/MockUAS.cc
new file mode 100644
index 0000000..d000a69
--- /dev/null
+++ b/src/qgcunittest/MockUAS.cc
@@ -0,0 +1,21 @@
+#include "MockUAS.h"
+
+QString MockUAS::_bogusStaticString;
+
+MockUAS::MockUAS(void) :
+    _systemType(MAV_TYPE_QUADROTOR),
+    _systemId(1)
+{
+    
+}
+
+void MockUAS::setMockParametersAndSignal(MockQGCUASParamManager::ParamMap_t& map)
+{
+    _paramManager.setMockParameters(map);
+    
+    QMapIterator<QString, QVariant> i(map);
+    while (i.hasNext()) {
+        i.next();
+        emit parameterChanged(_systemId, 0, i.key(), i.value());
+    }
+}
\ No newline at end of file
diff --git a/src/qgcunittest/MockUAS.h b/src/qgcunittest/MockUAS.h
new file mode 100644
index 0000000..a68624a
--- /dev/null
+++ b/src/qgcunittest/MockUAS.h
@@ -0,0 +1,161 @@
+#ifndef MOCKUAS_H
+#define MOCKUAS_H
+
+#include "UASInterface.h"
+#include "MockQGCUASParamManager.h"
+
+#include <limits>
+
+/// @file
+///     @brief This is a mock implementation of a UAS used for writing Unit Tests. Normal usage is to
+///         call MockUASManager::setMockActiveUAS to set it to the active mock UAS>
+///
+///     @author Don Gagne <don@thegagnes.com>
+
+class MockUAS : public UASInterface
+{
+    Q_OBJECT
+    
+signals:
+    // The following UASInterface signals are supported
+    void parameterChanged(int uas, int component, QString parameterName, QVariant value);
+    void remoteControlChannelRawChanged(int channelId, float raw);
+    
+public:
+    // Implemented UASInterface overrides
+    virtual int getSystemType(void) { return _systemType; }
+    virtual int getUASID(void) const { return _systemId; }
+    virtual QGCUASParamManagerInterface* getParamManager() { return &_paramManager; };
+    
+public:
+    // MockUAS methods
+    MockUAS(void);
+    
+    // Use these methods to setup/control the mock UAS
+    
+    void setMockSystemType(int systemType) { _systemType = systemType; }
+    void setMockSystemId(int systemId) { _systemId = systemId; }
+    
+    /// @return returns mock QGCUASParamManager associated with the UAS. This mock implementation
+    /// allows you to simulate parameter input and validate parameter setting
+    MockQGCUASParamManager* getMockQGCUASParamManager(void) { return &_paramManager; }
+    
+    /// Sets the parameter map into the mock QGCUASParamManager and signals parameterChanged for
+    /// each param
+    void setMockParametersAndSignal(MockQGCUASParamManager::ParamMap_t& map);
+    
+    void emitRemoteControlChannelRawChanged(int channel, float raw) { emit remoteControlChannelRawChanged(channel, raw); }
+    
+public:
+    // Unimplemented UASInterface overrides
+    virtual QString getUASName() const { Q_ASSERT(false); return _bogusString; };
+    virtual const QString& getShortState() const { Q_ASSERT(false); return _bogusString; };
+    virtual const QString& getShortMode() const { Q_ASSERT(false); return _bogusString; };
+    static QString getShortModeTextFor(int id) { Q_UNUSED(id); Q_ASSERT(false); return _bogusStaticString; };
+    virtual quint64 getUptime() const { Q_ASSERT(false); return 0; };
+    virtual int getCommunicationStatus() const { Q_ASSERT(false); return 0; };
+    virtual double getLocalX() const { Q_ASSERT(false); return std::numeric_limits<double>::quiet_NaN(); };
+    virtual double getLocalY() const { Q_ASSERT(false); return std::numeric_limits<double>::quiet_NaN(); };
+    virtual double getLocalZ() const { Q_ASSERT(false); return std::numeric_limits<double>::quiet_NaN(); };
+    virtual bool localPositionKnown() const { Q_ASSERT(false); return false; };
+    virtual double getLatitude() const { Q_ASSERT(false); return std::numeric_limits<double>::quiet_NaN(); };
+    virtual double getLongitude() const { Q_ASSERT(false); return std::numeric_limits<double>::quiet_NaN(); };
+    virtual double getAltitudeAMSL() const { Q_ASSERT(false); return std::numeric_limits<double>::quiet_NaN(); };
+    virtual double getAltitudeRelative() const { Q_ASSERT(false); return std::numeric_limits<double>::quiet_NaN(); };
+    virtual bool globalPositionKnown() const { Q_ASSERT(false); return false; };
+    virtual double getRoll() const { Q_ASSERT(false); return std::numeric_limits<double>::quiet_NaN(); };
+    virtual double getPitch() const { Q_ASSERT(false); return std::numeric_limits<double>::quiet_NaN(); };
+    virtual double getYaw() const { Q_ASSERT(false); return std::numeric_limits<double>::quiet_NaN(); };
+    virtual bool getSelected() const { Q_ASSERT(false); return false; };
+#if defined(QGC_PROTOBUF_ENABLED) && defined(QGC_USE_PIXHAWK_MESSAGES)
+    virtual px::GLOverlay getOverlay() { Q_ASSERT(false); };
+    virtual px::GLOverlay getOverlay(qreal& receivedTimestamp) { Q_ASSERT(false); };
+    virtual px::ObstacleList getObstacleList() { Q_ASSERT(false); };
+    virtual px::ObstacleList getObstacleList(qreal& receivedTimestamp) { Q_ASSERT(false); };
+    virtual px::Path getPath() { Q_ASSERT(false); };
+    virtual px::Path getPath(qreal& receivedTimestamp) { Q_ASSERT(false); };
+    virtual px::PointCloudXYZRGB getPointCloud() { Q_ASSERT(false); };
+    virtual px::PointCloudXYZRGB getPointCloud(qreal& receivedTimestamp) { Q_ASSERT(false); };
+    virtual px::RGBDImage getRGBDImage() { Q_ASSERT(false); };
+    virtual px::RGBDImage getRGBDImage(qreal& receivedTimestamp) { Q_ASSERT(false); };
+#endif
+    virtual bool isArmed() const { Q_ASSERT(false); return false; };
+    virtual int getAirframe() const { Q_ASSERT(false); return 0; };
+    virtual UASWaypointManager* getWaypointManager(void) { Q_ASSERT(false); return NULL; };
+    virtual QList<LinkInterface*>* getLinks() { Q_ASSERT(false); return NULL; };
+    virtual bool systemCanReverse() const { Q_ASSERT(false); return false; };
+    virtual QString getSystemTypeName() { Q_ASSERT(false); return _bogusString; };
+    virtual int getAutopilotType() { Q_ASSERT(false); return 0; };
+    virtual QString getAutopilotTypeName() { Q_ASSERT(false); return _bogusString; };
+    virtual void setAutopilotType(int apType) { Q_UNUSED(apType); Q_ASSERT(false); };
+    virtual QMap<int, QString> getComponents() { Q_ASSERT(false); return _bogusMapIntQString; };
+    virtual QList<QAction*> getActions() const { Q_ASSERT(false); return _bogusQListQActionPointer; };
+
+public slots:
+    // Unimplemented UASInterface overrides
+    virtual void setUASName(const QString& name) { Q_UNUSED(name); Q_ASSERT(false); };
+    virtual void executeCommand(MAV_CMD command) { Q_UNUSED(command); Q_ASSERT(false); };
+    virtual void executeCommand(MAV_CMD command, int confirmation, float param1, float param2, float param3, float param4, float param5, float param6, float param7, int component) { Q_UNUSED(command); Q_UNUSED(confirmation); Q_UNUSED(param1); Q_UNUSED(param2); Q_UNUSED(param3); Q_UNUSED(param4); Q_UNUSED(param5); Q_UNUSED(param6); Q_UNUSED(param7); Q_UNUSED(component); Q_ASSERT(false); };
+    virtual void executeCommandAck(int num, bool success) { Q_UNUSED(num); Q_UNUSED(success); Q_ASSERT(false); };
+    virtual void setAirframe(int airframe) { Q_UNUSED(airframe); Q_ASSERT(false); };
+    virtual void launch() { Q_ASSERT(false); };
+    virtual void home() { Q_ASSERT(false); };
+    virtual void land() { Q_ASSERT(false); };
+    virtual void pairRX(int rxType, int rxSubType) { Q_UNUSED(rxType); Q_UNUSED(rxSubType); Q_ASSERT(false); };
+    virtual void halt() { Q_ASSERT(false); };
+    virtual void go() { Q_ASSERT(false); };
+    virtual void setMode(uint8_t newBaseMode, uint32_t newCustomMode) { Q_UNUSED(newBaseMode); Q_UNUSED(newCustomMode); Q_ASSERT(false); };
+    virtual void emergencySTOP() { Q_ASSERT(false); };
+    virtual bool emergencyKILL() { Q_ASSERT(false); return false; };
+    virtual void shutdown() { Q_ASSERT(false); };
+    virtual void setTargetPosition(float x, float y, float z, float yaw) { Q_UNUSED(x); Q_UNUSED(y); Q_UNUSED(z); Q_UNUSED(yaw); Q_ASSERT(false); };
+    virtual void setLocalOriginAtCurrentGPSPosition() { Q_ASSERT(false); };
+    virtual void setHomePosition(double lat, double lon, double alt) { Q_UNUSED(lat); Q_UNUSED(lon); Q_UNUSED(alt); Q_ASSERT(false); };
+    virtual void requestParameters() { Q_ASSERT(false); };
+    virtual void requestParameter(int component, const QString& parameter) { Q_UNUSED(component); Q_UNUSED(parameter); Q_ASSERT(false); };
+    virtual void writeParametersToStorage() { Q_ASSERT(false); };
+    virtual void readParametersFromStorage() { Q_ASSERT(false); };
+    virtual void setParameter(const int component, const QString& id, const QVariant& value)
+        { Q_UNUSED(component); Q_UNUSED(id); Q_UNUSED(value); Q_ASSERT(false); };
+    virtual void addLink(LinkInterface* link) { Q_UNUSED(link); Q_ASSERT(false); };
+    virtual void setSelected() { Q_ASSERT(false); }
+    virtual void enableAllDataTransmission(int rate) { Q_UNUSED(rate); Q_ASSERT(false); };
+    virtual void enableRawSensorDataTransmission(int rate) { Q_UNUSED(rate); Q_ASSERT(false); };
+    virtual void enableExtendedSystemStatusTransmission(int rate) { Q_UNUSED(rate); Q_ASSERT(false); };
+    virtual void enableRCChannelDataTransmission(int rate) { Q_UNUSED(rate); Q_ASSERT(false); };
+    virtual void enableRawControllerDataTransmission(int rate) { Q_UNUSED(rate); Q_ASSERT(false); };
+    virtual void enablePositionTransmission(int rate) { Q_UNUSED(rate); Q_ASSERT(false); };
+    virtual void enableExtra1Transmission(int rate) { Q_UNUSED(rate); Q_ASSERT(false); };
+    virtual void enableExtra2Transmission(int rate) { Q_UNUSED(rate); Q_ASSERT(false); };
+    virtual void enableExtra3Transmission(int rate) { Q_UNUSED(rate); Q_ASSERT(false); };
+    virtual void setLocalPositionSetpoint(float x, float y, float z, float yaw)
+        { Q_UNUSED(x); Q_UNUSED(y); Q_UNUSED(z); Q_UNUSED(yaw); Q_ASSERT(false); };
+    virtual void setLocalPositionOffset(float x, float y, float z, float yaw) { Q_UNUSED(x); Q_UNUSED(y); Q_UNUSED(z); Q_UNUSED(yaw); Q_ASSERT(false); };
+    virtual void startRadioControlCalibration() { Q_ASSERT(false); };
+    virtual void startMagnetometerCalibration() { Q_ASSERT(false); };
+    virtual void startGyroscopeCalibration() { Q_ASSERT(false); };
+    virtual void startPressureCalibration() { Q_ASSERT(false); };
+    virtual void setBatterySpecs(const QString& specs) { Q_UNUSED(specs); Q_ASSERT(false); };
+    virtual QString getBatterySpecs() { Q_ASSERT(false); return _bogusString; };
+    virtual void sendHilState(quint64 time_us, float roll, float pitch, float yaw, float rollspeed, float pitchspeed, float yawspeed, double lat, double lon, double alt, float vx, float vy, float vz, float ind_airspeed, float true_airspeed, float xacc, float yacc, float zacc)
+        { Q_UNUSED(time_us); Q_UNUSED(roll); Q_UNUSED(pitch); Q_UNUSED(yaw); Q_UNUSED(rollspeed); Q_UNUSED(pitchspeed); Q_UNUSED(yawspeed); Q_UNUSED(lat); Q_UNUSED(lon); Q_UNUSED(alt); Q_UNUSED(vx); Q_UNUSED(vy); Q_UNUSED(vz); Q_UNUSED(ind_airspeed); Q_UNUSED(true_airspeed); Q_UNUSED(xacc); Q_UNUSED(yacc); Q_UNUSED(zacc); Q_ASSERT(false); };
+    virtual void sendHilSensors(quint64 time_us, float xacc, float yacc, float zacc, float rollspeed, float pitchspeed, float yawspeed, float xmag, float ymag, float zmag, float abs_pressure, float diff_pressure, float pressure_alt, float temperature, quint32 fields_changed)
+        { Q_UNUSED(time_us); Q_UNUSED(xacc); Q_UNUSED(yacc); Q_UNUSED(zacc); Q_UNUSED(rollspeed); Q_UNUSED(pitchspeed); Q_UNUSED(yawspeed); Q_UNUSED(xmag); Q_UNUSED(ymag); Q_UNUSED(zmag); Q_UNUSED(abs_pressure); Q_UNUSED(diff_pressure); Q_UNUSED(pressure_alt); Q_UNUSED(temperature); Q_UNUSED(fields_changed); Q_ASSERT(false); };
+    virtual void sendHilGps(quint64 time_us, double lat, double lon, double alt, int fix_type, float eph, float epv, float vel, float vn, float ve, float vd, float cog, int satellites)
+        { Q_UNUSED(time_us); Q_UNUSED(lat); Q_UNUSED(lon); Q_UNUSED(alt); Q_UNUSED(fix_type); Q_UNUSED(eph); Q_UNUSED(epv); Q_UNUSED(vel); Q_UNUSED(vn); Q_UNUSED(ve); Q_UNUSED(vd); Q_UNUSED(cog); Q_UNUSED(satellites); Q_ASSERT(false); };
+    
+private:
+    int                 _systemType;
+    int                 _systemId;
+    
+    MockQGCUASParamManager _paramManager;
+
+    // Bogus variables used for return types of NYI methods
+    QString             _bogusString;
+    static QString      _bogusStaticString;
+    QMap<int, QString>  _bogusMapIntQString;
+    QList<QAction*>     _bogusQListQActionPointer;
+    QList<int>          _bogusQListInt;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/qgcunittest/MockUASManager.cc b/src/qgcunittest/MockUASManager.cc
new file mode 100644
index 0000000..5f3093c
--- /dev/null
+++ b/src/qgcunittest/MockUASManager.cc
@@ -0,0 +1,34 @@
+#include "MockUASManager.h"
+
+MockUASManager::MockUASManager(void) :
+    _mockUAS(NULL)
+{
+    
+}
+
+UASInterface* MockUASManager::getActiveUAS(void)
+{
+    return _mockUAS;
+}
+
+void MockUASManager::setMockActiveUAS(MockUAS* mockUAS)
+{
+    // Signal components that the last UAS is no longer active.
+    if (_mockUAS != NULL) {
+        emit activeUASStatusChanged(_mockUAS, false);
+        emit activeUASStatusChanged(_mockUAS->getUASID(), false);
+    }
+    _mockUAS = mockUAS;
+    
+    // And signal that a new UAS is.
+    emit activeUASSet(_mockUAS);
+    if (_mockUAS)
+    {
+        // We don't support swiching between different UAS
+        //_mockUAS->setSelected();
+        emit activeUASSet(_mockUAS->getUASID());
+        emit activeUASStatusChanged(_mockUAS, true);
+        emit activeUASStatusChanged(_mockUAS->getUASID(), true);
+    }
+}
+
diff --git a/src/qgcunittest/MockUASManager.h b/src/qgcunittest/MockUASManager.h
new file mode 100644
index 0000000..5541a05
--- /dev/null
+++ b/src/qgcunittest/MockUASManager.h
@@ -0,0 +1,101 @@
+#ifndef MOCKUASMANAGER_H
+#define MOCKUASMANAGER_H
+
+#include "UASManagerInterface.h"
+#include "MockUAS.h"
+
+/// @file
+///     @brief This is a mock implementation of a UASManager used for writing Unit Tests. In order
+///         to use it you must call UASManager::setMockUASManager which will then cause all further
+///         calls to UASManager::instance to return the mock UASManager instead of the normal one.
+///
+///     @author Don Gagne <don@thegagnes.com>
+
+class MockUASManager : public UASManagerInterface
+{
+    Q_OBJECT
+    
+signals:
+    // The following signals from UASManager interface are supported
+    void activeUASSet(UASInterface* UAS);
+    void activeUASSet(int systemId);
+    void activeUASStatusChanged(UASInterface* UAS, bool active);
+    void activeUASStatusChanged(int systemId, bool active);
+    
+public:
+    // Implemented UASManagerInterface overrides
+    virtual UASInterface* getActiveUAS(void);
+    
+public:
+    // MockUASManager methods
+    MockUASManager(void);
+    
+    /// Sets the currently active mock UAS
+    /// @param mockUAS new mock uas, NULL for no active UAS
+    void setMockActiveUAS(MockUAS* mockUAS);
+
+public:
+    // Unimplemented UASManagerInterface overrides
+    virtual UASWaypointManager *getActiveUASWaypointManager() { Q_ASSERT(false); return NULL; }
+    virtual UASInterface* silentGetActiveUAS() { Q_ASSERT(false); return NULL; }
+    virtual UASInterface* getUASForId(int id) { Q_ASSERT(false); Q_UNUSED(id); return NULL; }
+    virtual QList<UASInterface*> getUASList() { Q_ASSERT(false); return _bogusQListUASInterface; }
+    virtual double getHomeLatitude() const  { Q_ASSERT(false); return std::numeric_limits<double>::quiet_NaN(); }
+    virtual double getHomeLongitude() const  { Q_ASSERT(false); return std::numeric_limits<double>::quiet_NaN(); }
+    virtual double getHomeAltitude() const { Q_ASSERT(false); return std::numeric_limits<double>::quiet_NaN(); }
+    virtual int getHomeFrame() const { Q_ASSERT(false); return 0; }
+    virtual Eigen::Vector3d wgs84ToEcef(const double & latitude, const double & longitude, const double & altitude)
+        { Q_ASSERT(false); Q_UNUSED(latitude); Q_UNUSED(longitude); Q_UNUSED(altitude); return _bogusEigenVector3d; }
+    virtual Eigen::Vector3d ecefToEnu(const Eigen::Vector3d & ecef)
+        { Q_ASSERT(false); Q_UNUSED(ecef); return _bogusEigenVector3d; }
+    virtual void wgs84ToEnu(const double& lat, const double& lon, const double& alt, double* east, double* north, double* up)
+        { Q_ASSERT(false); Q_UNUSED(lat); Q_UNUSED(lon); Q_UNUSED(alt); Q_UNUSED(east); Q_UNUSED(north); Q_UNUSED(up); }
+    virtual void enuToWgs84(const double& x, const double& y, const double& z, double* lat, double* lon, double* alt)
+        { Q_ASSERT(false); Q_UNUSED(x); Q_UNUSED(y); Q_UNUSED(z); Q_UNUSED(lat); Q_UNUSED(lon); Q_UNUSED(alt); }
+    virtual void nedToWgs84(const double& x, const double& y, const double& z, double* lat, double* lon, double* alt)
+        { Q_ASSERT(false); Q_UNUSED(x); Q_UNUSED(y); Q_UNUSED(z); Q_UNUSED(lat); Q_UNUSED(lon); Q_UNUSED(alt); }
+    virtual void getLocalNEDSafetyLimits(double* x1, double* y1, double* z1, double* x2, double* y2, double* z2)
+        { Q_ASSERT(false); Q_UNUSED(x1); Q_UNUSED(y1); Q_UNUSED(z1); Q_UNUSED(x2); Q_UNUSED(y2); Q_UNUSED(z2); }
+    virtual bool isInLocalNEDSafetyLimits(double x, double y, double z)
+        { Q_ASSERT(false); Q_UNUSED(x); Q_UNUSED(y); Q_UNUSED(z); return false; }
+    
+public slots:
+    // Unimplemented UASManagerInterface overrides
+    virtual void setActiveUAS(UASInterface* UAS) { Q_ASSERT(false); Q_UNUSED(UAS); }
+    virtual void addUAS(UASInterface* UAS) { Q_ASSERT(false); Q_UNUSED(UAS); }
+    virtual void removeUAS(UASInterface* uas) { Q_ASSERT(false); Q_UNUSED(uas);}
+    virtual bool launchActiveUAS() { Q_ASSERT(false); return false; }
+    virtual bool haltActiveUAS() { Q_ASSERT(false); return false; }
+    virtual bool continueActiveUAS() { Q_ASSERT(false); return false; }
+    virtual bool returnActiveUAS() { Q_ASSERT(false); return false; }
+    virtual bool stopActiveUAS() { Q_ASSERT(false); return false; }
+    virtual bool killActiveUAS() { Q_ASSERT(false); return false; }
+    virtual void configureActiveUAS() { Q_ASSERT(false); }
+    virtual bool shutdownActiveUAS() { Q_ASSERT(false); return false; }
+    virtual bool setHomePosition(double lat, double lon, double alt)
+        { Q_ASSERT(false); Q_UNUSED(lat); Q_UNUSED(lon); Q_UNUSED(alt); return false; }
+    virtual bool setHomePositionAndNotify(double lat, double lon, double alt)
+        { Q_ASSERT(false); Q_UNUSED(lat); Q_UNUSED(lon); Q_UNUSED(alt); return false; }
+    virtual void setLocalNEDSafetyBorders(double x1, double y1, double z1, double x2, double y2, double z2)
+        { Q_ASSERT(false); Q_UNUSED(x1); Q_UNUSED(y1); Q_UNUSED(z1); Q_UNUSED(x2); Q_UNUSED(y2); Q_UNUSED(z2); }
+    virtual void uavChangedHomePosition(int uav, double lat, double lon, double alt)
+        { Q_ASSERT(false); Q_UNUSED(uav); Q_UNUSED(lat); Q_UNUSED(lon); Q_UNUSED(alt); }
+    virtual void loadSettings() { Q_ASSERT(false); }
+    virtual void storeSettings() { Q_ASSERT(false); }
+    
+private:
+    MockUAS*                _mockUAS;
+    
+    // Bogus variables used for return types of NYI methods
+    QList<UASInterface*>    _bogusQListUASInterface;
+    Eigen::Vector3d         _bogusEigenVector3d;
+    
+public:
+    /* Need to align struct pointer to prevent a memory assertion:
+     * See http://eigen.tuxfamily.org/dox-devel/TopicUnalignedArrayAssert.html
+     * for details
+     */
+    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+};
+
+#endif
\ No newline at end of file