[libcalamares] Implement Handler's synchronous query()

- Steal code from existing tests for a synchronous HTTP get,
   then hand it off to the handler.
 - Extend tests with Handler interpreting the same data.
This commit is contained in:
Adriaan de Groot 2019-05-02 08:33:29 -04:00
parent 9bc8d28800
commit 1da580f43d
3 changed files with 94 additions and 3 deletions

View File

@ -22,6 +22,7 @@
#ifdef QT_XML_LIB #ifdef QT_XML_LIB
#include "GeoIPXML.h" #include "GeoIPXML.h"
#endif #endif
#include "Handler.h"
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkReply> #include <QNetworkReply>
@ -219,14 +220,18 @@ synchronous_get( const char* urlstring )
#define CHECK_GET(t, selector, url) \ #define CHECK_GET(t, selector, url) \
{ \ { \
auto tz = GeoIP##t( selector ).processReply( synchronous_get( url ) ); \ auto tz = GeoIP##t( selector ).processReply( synchronous_get( url ) ); \
qDebug() << tz; \
QCOMPARE( default_tz, tz ); \ QCOMPARE( default_tz, tz ); \
auto tz2 = CalamaresUtils::GeoIP::Handler( ""#t, url, selector ).query(); \
qDebug() << tz2; \
QCOMPARE( default_tz, tz2 ); \
} }
void GeoIPTests::testGet() void GeoIPTests::testGet()
{ {
if ( !QProcessEnvironment::systemEnvironment().contains( QStringLiteral("TEST_HTTP_GET") ) ) if ( !QProcessEnvironment::systemEnvironment().contains( QStringLiteral("TEST_HTTP_GET") ) )
{ {
qDebug() << "Skipping HTTP GET tests"; qDebug() << "Skipping HTTP GET tests, set TEST_HTTP_GET environment variable to enable";
return; return;
} }

View File

@ -18,23 +18,80 @@
#include "Handler.h" #include "Handler.h"
#include "GeoIPJSON.h"
#if defined(QT_XML_LIB)
#include "GeoIPXML.h"
#endif
#include "utils/Logger.h"
#include <QEventLoop>
#include <QNetworkRequest>
#include <QNetworkReply>
namespace CalamaresUtils::GeoIP namespace CalamaresUtils::GeoIP
{ {
Handler::Handler() Handler::Handler()
: m_interface( nullptr )
{ {
} }
Handler::Handler( const QString& implementation, const QString& url, const QString& selector )
: m_interface( nullptr )
, m_url( url )
{
if ( implementation.compare( "json", Qt::CaseInsensitive ) == 0 )
{
m_interface = new GeoIPJSON( selector );
}
#if defined(QT_XML_LIB)
else if ( implementation.compare( "xml", Qt::CaseInsensitive ) == 0 )
{
m_interface = new GeoIPXML( selector );
}
#endif
else
{
cWarning() << "GeoIP Style" << implementation << "is not recognized.";
}
}
Handler::~Handler()
{
delete m_interface;
}
bool bool
Handler::isValid() const Handler::isValid() const
{ {
return false; return m_interface;
} }
static QByteArray
synchronous_get( const QString& urlstring )
{
QUrl url( urlstring );
QNetworkAccessManager manager;
QEventLoop loop;
QObject::connect( &manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit );
QNetworkRequest request( url );
QNetworkReply* reply = manager.get( request );
loop.exec();
reply->deleteLater();
return reply->readAll();
}
RegionZonePair RegionZonePair
Handler::query() const Handler::query() const
{ {
if ( !isValid() )
return RegionZonePair(); return RegionZonePair();
return m_interface->processReply( synchronous_get( m_url ) );
} }
} // namespace } // namespace

View File

@ -21,6 +21,9 @@
#include "Interface.h" #include "Interface.h"
#include <QString>
#include <QVariantMap>
namespace CalamaresUtils {} namespace CalamaresUtils {}
namespace CalamaresUtils::GeoIP namespace CalamaresUtils::GeoIP
{ {
@ -37,10 +40,36 @@ class DLLEXPORT Handler
public: public:
/** @brief An unconfigured handler; this always returns errors. */ /** @brief An unconfigured handler; this always returns errors. */
Handler(); Handler();
/** @brief A handler for a specific GeoIP source.
*
* The @p implementation name selects an implementation; currently JSON and XML
* are supported. The @p url is retrieved by query() and then the @p selector
* is used to select something from the data returned by the @url.
*/
Handler( const QString& implementation, const QString& url, const QString& selector );
/** @brief A handler for a specific GeoIP source.
*
* This is like the 3-QString Handler constructor, except the strings
* are extracted from the map, which is typically part of the configuration
* of a Calamares module. The strings are fetched from these keys:
* - implementation from "style" or "geoipStyle" (if the first does not exist)
* - url from "url" or "geoipUrl" (if the first does not exist)
* - selector from "selector" or "geoipSelector" (if the first does not exist)
* Unlike the 3-QString Handler constructor, this also understands implementations
* "legacy" and blank, which are interpreted as "JSON", except that the url is extended
* by "/json/" before fetching.
*/
Handler( const QVariantMap& config );
~Handler();
RegionZonePair query() const; RegionZonePair query() const;
bool isValid() const; bool isValid() const;
private:
Interface* m_interface;
const QString m_url;
}; };
} // namespace } // namespace