Skip to content

Commit

Permalink
Merge 4c43f3c into 73eb05d
Browse files Browse the repository at this point in the history
  • Loading branch information
ugnelis committed May 2, 2018
2 parents 73eb05d + 4c43f3c commit e116422
Show file tree
Hide file tree
Showing 8 changed files with 303 additions and 11 deletions.
62 changes: 62 additions & 0 deletions src/utils/customnetworkreply.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include "customnetworkreply.h"

CustomNetworkReply::CustomNetworkReply(QObject *parent)
: QNetworkReply(parent), content(nullptr), offset(0) {
}

CustomNetworkReply::~CustomNetworkReply() {
}

void CustomNetworkReply::setHttpStatusCode(int code, const QByteArray &statusText) {
setAttribute(QNetworkRequest::HttpStatusCodeAttribute, code);
if (statusText.isNull())
return;

setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, statusText);
}

void CustomNetworkReply::setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value) {
QNetworkReply::setHeader(header, value);
}

void CustomNetworkReply::setContentType(const QByteArray &contentType) {
setHeader(QNetworkRequest::ContentTypeHeader, contentType);
}

void CustomNetworkReply::setContent(const QString &content) {
setContent(content.toUtf8());
}

void CustomNetworkReply::setContent(const QByteArray &content) {
this->content = content;
offset = 0;

open(ReadOnly | Unbuffered);
setHeader(QNetworkRequest::ContentLengthHeader, QVariant(content.size()));

QTimer::singleShot(0, this, SIGNAL(readyRead()));
QTimer::singleShot(0, this, SIGNAL(finished()));
}

void CustomNetworkReply::abort() {
// No operation.
}

qint64 CustomNetworkReply::bytesAvailable() const {
return content.size() - offset + QIODevice::bytesAvailable();
}

bool CustomNetworkReply::isSequential() const {
return true;
}

qint64 CustomNetworkReply::readData(char *data, qint64 maxSize) {
if (offset >= content.size())
return -1;

qint64 number = qMin(maxSize, content.size() - offset);
memcpy(data, content.constData() + offset, number);
offset += number;

return number;
}
93 changes: 93 additions & 0 deletions src/utils/customnetworkreply.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#ifndef INSTANT_TRANSLATOR_CUSTOMNETWORKREPLY_H
#define INSTANT_TRANSLATOR_CUSTOMNETWORKREPLY_H

#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QBuffer>
#include <QTimer>

/**
* Custom QNetworkReply class.
*/
class CustomNetworkReply : public QNetworkReply {
Q_OBJECT

public:
/**
* Constructs an object with parent object parent.
* @param parent Parent of an object may be viewed as the object's owner.
*/
explicit CustomNetworkReply(QObject *parent = nullptr);

/**
* Destructor.
*/
~CustomNetworkReply() override;

/**
*
* @param code
* @param statusText
*/
void setHttpStatusCode(int code, const QByteArray &statusText = QByteArray());

/**
* Sets the value of the known header header to be
* value, overriding any previously set headers.
* @param header Header.
* @param value Value.
*/
void setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value);

/**
* Set content type, e.g., "text/html".
* @param contentType Content type.
*/
void setContentType(const QByteArray &contentType);

/**
* Set content.
* @param content Content.
*/
void setContent(const QString &content);

/**
* Set content.
* @param content Content.
*/
void setContent(const QByteArray &content);

/**
* Aborts the operation immediately and close
* down any network connections still open.
*/
void abort() override;

/**
* Returns the number of bytes that are available for reading.
* @return Bytes that are available for reading.
*/
qint64 bytesAvailable() const override;

/**
* Returns true if this device is sequential; otherwise returns false.
* @return Returns true if this device is sequential.
*/
bool isSequential() const override;

protected:
/**
* Reads up to maxSize bytes from the device into data, and
* returns the number of bytes read or -1 if an error occurred.
* @param data Data.
* @param maxSize Max size.
* @return returns the number of bytes read or -1 if an error occurred.
*/
qint64 readData(char *data, qint64 maxSize) override;

private:
QByteArray content;
qint64 offset;
};

#endif //INSTANT_TRANSLATOR_CUSTOMNETWORKREPLY_H
4 changes: 4 additions & 0 deletions src/utils/requestmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ RequestManager::RequestManager(QObject *parent)
: QObject(parent), manager(new QNetworkAccessManager) {
}

RequestManager::RequestManager(QObject *parent, QNetworkAccessManager *manager)
: QObject(parent), manager(manager) {
}

RequestManager::~RequestManager() {
delete manager;
}
Expand Down
7 changes: 7 additions & 0 deletions src/utils/requestmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ Q_OBJECT
*/
explicit RequestManager(QObject *parent = nullptr);

/**
* Constructs an object with parent object parent.
* @param parent Parent of an object may be viewed as the object's owner.
* @param manager Network access manager.
*/
RequestManager(QObject *parent, QNetworkAccessManager *manager);

/**
* Destructor.
*/
Expand Down
21 changes: 18 additions & 3 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
set(CMAKE_CXX_STANDARD 11)

# Find includes in corresponding build directories.
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
# Instruct CMake to run uic automatically when needed.
set(CMAKE_AUTOUIC ON)
# Add a compiler flag.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")

# Find the Qt libraries.
find_package(Qt5Widgets REQUIRED)
Expand All @@ -23,15 +33,20 @@ include_directories("${PROJECT_SOURCE_DIR}/src")

# Source files.
set(SOURCE_FILES
language_test.cpp
utils/language_test.cpp
${PROJECT_SOURCE_DIR}/src/utils/language.cpp
${PROJECT_SOURCE_DIR}/src/utils/language.h)
${PROJECT_SOURCE_DIR}/src/utils/language.h
utils/requestmanager_test.cpp
${PROJECT_SOURCE_DIR}/src/utils/requestmanager.cpp
${PROJECT_SOURCE_DIR}/src/utils/requestmanager.h
${PROJECT_SOURCE_DIR}/src/utils/customnetworkreply.cpp
${PROJECT_SOURCE_DIR}/src/utils/customnetworkreply.h)

# Tell CMake to create the executable.
add_executable(unit_tests ${SOURCE_FILES} ${RESOURCE_FILES_ADDED} ${UI_HEADERS})

# Use the Widgets module from Qt5.
target_link_libraries(unit_tests ${QT5_LIBRARIES} gtest_main)
target_link_libraries(unit_tests ${QT5_LIBRARIES} gtest_main gmock_main)

# Add tests.
add_test(
Expand Down
8 changes: 0 additions & 8 deletions tests/language_test.cpp

This file was deleted.

35 changes: 35 additions & 0 deletions tests/utils/language_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include <gtest/gtest.h>
#include <QStringList>
#include "utils/language.h"

TEST(LanguageTests, getCode_ConvertLanguageToName_True) {
Language language;
ASSERT_EQ("lt", language.getCode("Lithuanian"));
}

TEST(LanguageTests, getName_ConvertCodeToName_True) {
Language language;
ASSERT_EQ("Lithuanian", language.getName("lt"));
}

TEST(LanguageTests, getLanguages_ConvertCodesToLanguages_True) {
Language language;
QStringList codesList;
codesList.append("lt");
codesList.append("en");
QStringList languagesList = language.getLanguages(codesList);
ASSERT_EQ(2, languagesList.size());
ASSERT_EQ("Lithuanian", languagesList.at(0));
ASSERT_EQ("English", languagesList.at(1));
}

TEST(LanguageTests, getCodes_ConvertLanguagesToCodes_True) {
Language language;
QStringList languagesList;
languagesList.append("Lithuanian");
languagesList.append("English");
QStringList codesList = language.getCodes(languagesList);
ASSERT_EQ(2, languagesList.size());
ASSERT_EQ("lt", codesList.at(0));
ASSERT_EQ("en", codesList.at(1));
}
84 changes: 84 additions & 0 deletions tests/utils/requestmanager_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <QApplication>
#include <QJsonObject>
#include <QJsonDocument>
#include <QNetworkAccessManager>
#include "utils/requestmanager.h"
#include "utils/customnetworkreply.h"

class MockQNetworkAccessManager : public QNetworkAccessManager {
public:
explicit MockQNetworkAccessManager(QObject *parent = nullptr) : QNetworkAccessManager(parent) {}

protected:
QNetworkReply *createRequest(Operation op, const QNetworkRequest &originalReq,
QIODevice *outgoingData = Q_NULLPTR) override {
CustomNetworkReply *reply = new CustomNetworkReply();
reply->setHttpStatusCode(200, "OK");
reply->setContentType("application/json");
reply->setContent(QString("{\"data\":{\"translations\":[{\"translatedText\":\"Hello\"}]}}"));

return reply;
}
};

TEST(RequestManagerTests, postRequest_SendPostRequest_True) {
int argc = 0;
char **argv = 0;
QCoreApplication app(argc, argv);

// Format Json object.
QJsonObject postJsonObject;
postJsonObject["source"] = "lt";
postJsonObject["target"] = "en";
postJsonObject["format"] = "text";
postJsonObject["q"] = "Labas";

QJsonDocument postJsonDocument(postJsonObject);

// Make request.
QUrl url("https://randomurl.com/");
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

// Send request.
MockQNetworkAccessManager *manager = new MockQNetworkAccessManager();

RequestManager requestManager(nullptr, manager);
requestManager.postRequest(request, postJsonDocument.toJson());

// Test.
QString expected = "{\"data\":{\"translations\":[{\"translatedText\":\"Hello\"}]}}";
ASSERT_EQ(expected, requestManager.getReply());
}

TEST(RequestManagerTests, getRequest_SendGetRequest_True) {
int argc = 0;
char **argv = 0;
QCoreApplication app(argc, argv);

// Format Json object.
QJsonObject postJsonObject;
postJsonObject["source"] = "lt";
postJsonObject["target"] = "en";
postJsonObject["format"] = "text";
postJsonObject["q"] = "Labas";

QJsonDocument postJsonDocument(postJsonObject);

// Make request.
QUrl url("https://randomurl.com/");
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

// Send request.
MockQNetworkAccessManager *manager = new MockQNetworkAccessManager();

RequestManager requestManager(nullptr, manager);
requestManager.getRequest(request);

// Test.
QString expected = "{\"data\":{\"translations\":[{\"translatedText\":\"Hello\"}]}}";
ASSERT_EQ(expected, requestManager.getReply());
}

0 comments on commit e116422

Please sign in to comment.