From 46145241fc617c8c5900d215a7e3fd5befd0a558 Mon Sep 17 00:00:00 2001 From: Quentin Rouland Date: Fri, 10 Jan 2025 21:33:48 +0100 Subject: [PATCH] Setup tests --- CMakeLists.txt | 20 +++- clickable.yaml | 2 +- main.cpp => main.in.cpp | 8 ++ plugins/Git/git.cpp | 1 - plugins/Git/libgit.cpp | 12 ++- po/utpass.qrouland.pot | 106 ++++++++++----------- tests/assets/archive.zip | Bin 0 -> 1072 bytes tests/assets/gpg/passphrase.txt | 1 + tests/assets/gpg/test_key.gpg | Bin 0 -> 591 bytes tests/assets/password-store/.gitattributes | 1 + tests/assets/password-store/.gpg-id | 1 + tests/assets/password-store/Test | 0 tests/assets/password-store/test.gpg | 1 + tests/plugins/CMakeLists.txt | 1 + tests/plugins/TestsUtils/CMakeLists.txt | 29 ++++++ tests/plugins/TestsUtils/plugin.cpp | 10 ++ tests/plugins/TestsUtils/plugin.h | 16 ++++ tests/plugins/TestsUtils/qmldir | 2 + tests/plugins/TestsUtils/utils.cpp | 37 +++++++ tests/plugins/TestsUtils/utils.h | 19 ++++ tests/unit/tst_git.qml | 12 +++ tests/unit/tst_pass.qml | 12 +++ tests/unit/tst_utils.qml | 15 +++ 23 files changed, 244 insertions(+), 62 deletions(-) rename main.cpp => main.in.cpp (80%) create mode 100644 tests/assets/archive.zip create mode 100644 tests/assets/gpg/passphrase.txt create mode 100644 tests/assets/gpg/test_key.gpg create mode 100644 tests/assets/password-store/.gitattributes create mode 100644 tests/assets/password-store/.gpg-id create mode 100644 tests/assets/password-store/Test create mode 100644 tests/assets/password-store/test.gpg create mode 100644 tests/plugins/CMakeLists.txt create mode 100644 tests/plugins/TestsUtils/CMakeLists.txt create mode 100644 tests/plugins/TestsUtils/plugin.cpp create mode 100644 tests/plugins/TestsUtils/plugin.h create mode 100644 tests/plugins/TestsUtils/qmldir create mode 100644 tests/plugins/TestsUtils/utils.cpp create mode 100644 tests/plugins/TestsUtils/utils.h create mode 100644 tests/unit/tst_git.qml create mode 100644 tests/unit/tst_pass.qml create mode 100644 tests/unit/tst_utils.qml diff --git a/CMakeLists.txt b/CMakeLists.txt index 161ee7f..6ebb068 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,9 +35,19 @@ set(DATA_DIR /) set(DESKTOP_FILE_NAME ${PROJECT_NAME}.desktop) -add_executable(${PROJECT_NAME} main.cpp - qml/pages/settings/ImportGitClone.qml) -qt5_use_modules(${PROJECT_NAME} Gui Qml Quick) +if(NOT TESTS_PATH) + set(TESTS_PATH "./tests") +endif() + +configure_file(main.in.cpp main.cpp) + +add_executable(${PROJECT_NAME} main.cpp) +qt5_use_modules(${PROJECT_NAME} Gui Qml Quick QuickTest) + +if(TESTS_RUNNER) + qt5_use_modules(${PROJECT_NAME} QuickTest) +endif() + install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}) @@ -77,5 +87,9 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${DESKTOP_FILE_NAME} DESTINATION ${DAT add_subdirectory(po) add_subdirectory(plugins) +if(TESTS_RUNNER) + add_subdirectory(tests/plugins) +endif() + add_custom_target(${PROJECT_NAME}_FILES ALL SOURCES ${PROJECT_SRC_FILES}) diff --git a/clickable.yaml b/clickable.yaml index 1a85269..f226e2c 100644 --- a/clickable.yaml +++ b/clickable.yaml @@ -4,7 +4,7 @@ kill: UTPass scripts: style: >- - echo 'Astyle :' && astyle --options=.astylerc main.cpp && astyle --options=.astylerc --recursive 'plugins/*.cpp,*.h' && echo 'Running QmlFormat' && find . -name "*.qml" -exec qmlformat -i {} \; && echo 'Success' + echo 'Running Astyle :' && astyle --options=.astylerc main.cpp && astyle --options=.astylerc --recursive 'plugins/*.cpp,*.h' && echo 'Running QmlFormat' && find . -name "*.qml" -exec qmlformat -i {} \; && echo 'Success' diff --git a/main.cpp b/main.in.cpp similarity index 80% rename from main.cpp rename to main.in.cpp index 3711bf5..baac230 100644 --- a/main.cpp +++ b/main.in.cpp @@ -6,6 +6,10 @@ #include +#ifdef TEST_RUNNER +#include +#endif + int main(int argc, char *argv[]) { qDebug() << "Starting app from main.cpp"; @@ -13,6 +17,7 @@ int main(int argc, char *argv[]) QGuiApplication::setApplicationName("utpass.qrouland"); +#ifndef TEST_RUNNER auto *view = new QQuickView(); view->setSource(QUrl(QStringLiteral("qml/Main.qml"))); view->setResizeMode(QQuickView::SizeRootObjectToView); @@ -23,4 +28,7 @@ int main(int argc, char *argv[]) Q_ARG(QVariant, QVariant::fromValue(mainView)) ); return QGuiApplication::exec(); +#else + return quick_test_main(argc, argv, "@TESTS_PATH@", "@TESTS_PATH@"); +#endif } diff --git a/plugins/Git/git.cpp b/plugins/Git/git.cpp index d9163cc..dc0557f 100644 --- a/plugins/Git/git.cpp +++ b/plugins/Git/git.cpp @@ -13,7 +13,6 @@ bool Git::clone(QString url, QString destination_dir_path) QDir tmp_dir(QStandardPaths::writableLocation( QStandardPaths::CacheLocation).append("/clone")); tmp_dir.removeRecursively(); - tmp_dir.mkpath("."); qDebug() << "Temp dir path is " << tmp_dir.absolutePath(); qDebug() << "Cloning " << url << " to tmp dir " << tmp_dir.absolutePath(); diff --git a/plugins/Git/libgit.cpp b/plugins/Git/libgit.cpp index fcbb610..8cc506c 100644 --- a/plugins/Git/libgit.cpp +++ b/plugins/Git/libgit.cpp @@ -33,10 +33,10 @@ int LibGit::credentials_cb(git_cred **out, const char *url, const char *username // store_error(error); // return GIT_EUSER; // } - // user = "user"; - // pass = "pass"; - // return git_cred_userpass_plaintext_new(out, user, pass); - return GIT_EUSER; + user = "pass"; + pass = "pass"; + return git_cred_userpass_plaintext_new(out, user, pass); + // return GIT_EUSER; } bool LibGit::clone(QString url, QString path) @@ -45,8 +45,12 @@ bool LibGit::clone(QString url, QString path) git_clone_options opts = GIT_CLONE_OPTIONS_INIT; opts.fetch_opts.callbacks.credentials = *credentials_cb; int ret = git_clone(&repo, url.toLocal8Bit().data(), path.toLocal8Bit().data(), &opts); + if (ret != 0) { + qDebug() << git_error_last()->message; + } if (repo) { git_repository_free(repo); } + return ret == 0; // TODO Clean error handling to return specifics errors for the ui } diff --git a/po/utpass.qrouland.pot b/po/utpass.qrouland.pot index d2a22db..7d7a88f 100644 --- a/po/utpass.qrouland.pot +++ b/po/utpass.qrouland.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: utpass.qrouland\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-10 14:39+0100\n" +"POT-Creation-Date: 2025-01-10 21:31+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: ../qml/components/FileDir.qml:71 +#: ../qml/components/FileDir.qml:69 msgid "Decryption failed !" msgstr "" @@ -37,19 +37,19 @@ msgstr "" msgid "Error !" msgstr "" -#: ../qml/dialogs/ErrorDialog.qml:15 +#: ../qml/dialogs/ErrorDialog.qml:16 msgid "Close" msgstr "" -#: ../qml/dialogs/PassphraseDialog.qml:7 +#: ../qml/dialogs/PassphraseDialog.qml:15 msgid "Authentication required" msgstr "" -#: ../qml/dialogs/PassphraseDialog.qml:8 +#: ../qml/dialogs/PassphraseDialog.qml:16 msgid "Enter passphrase:" msgstr "" -#: ../qml/dialogs/PassphraseDialog.qml:20 +#: ../qml/dialogs/PassphraseDialog.qml:21 msgid "passphrase" msgstr "" @@ -57,69 +57,65 @@ msgstr "" msgid "Success !" msgstr "" -#: ../qml/dialogs/SuccessDialog.qml:15 +#: ../qml/dialogs/SuccessDialog.qml:16 msgid "OK" msgstr "" -#: ../qml/pages/Info.qml:11 ../qml/pages/headers/MainHeader.qml:58 -msgid "Info" -msgstr "" - -#: ../qml/pages/Info.qml:50 +#: ../qml/pages/Info.qml:58 msgid "Version" msgstr "" -#: ../qml/pages/Info.qml:68 +#: ../qml/pages/Info.qml:77 msgid "Maintainer" msgstr "" -#: ../qml/pages/Info.qml:90 +#: ../qml/pages/Info.qml:102 msgid "Suggest improvement(s) or report a bug(s)" msgstr "" -#: ../qml/pages/Info.qml:94 +#: ../qml/pages/Info.qml:107 msgid "Access to the source code" msgstr "" -#: ../qml/pages/Info.qml:101 +#: ../qml/pages/Info.qml:115 msgid "Released under the terms of the GNU GPL v3" msgstr "" -#: ../qml/pages/PasswordList.qml:23 -msgid "Back" +#: ../qml/pages/Info.qml:123 ../qml/pages/headers/MainHeader.qml:33 +msgid "Info" msgstr "" -#: ../qml/pages/PasswordList.qml:43 +#: ../qml/pages/PasswordList.qml:26 msgid "" "No password found
You can import a password store zip in the settings" msgstr "" -#: ../qml/pages/headers/MainHeader.qml:8 ../qml/pages/headers/StackHeader.qml:8 +#: ../qml/pages/PasswordList.qml:65 +msgid "Back" +msgstr "" + +#: ../qml/pages/headers/MainHeader.qml:9 ../qml/pages/headers/StackHeader.qml:9 #: UTPass.desktop.in.h:1 msgid "UTPass" msgstr "" -#: ../qml/pages/headers/MainHeader.qml:23 -msgid "Search" -msgstr "" - -#: ../qml/pages/headers/MainHeader.qml:51 ../qml/pages/settings/Settings.qml:14 +#: ../qml/pages/headers/MainHeader.qml:26 ../qml/pages/settings/Settings.qml:68 msgid "Settings" msgstr "" -#: ../qml/pages/settings/ImportGitClone.qml:15 -msgid "Git Clone Import" +#: ../qml/pages/headers/MainHeader.qml:57 +msgid "Search" msgstr "" #: ../qml/pages/settings/ImportGitClone.qml:36 msgid "Repo Url" msgstr "" -#: ../qml/pages/settings/ImportGitClone.qml:44 +#: ../qml/pages/settings/ImportGitClone.qml:45 msgid "Git repo url" msgstr "" -#: ../qml/pages/settings/ImportGitClone.qml:50 +#: ../qml/pages/settings/ImportGitClone.qml:52 msgid "Clone" msgstr "" @@ -129,85 +125,89 @@ msgid "" "
Continue ?" msgstr "" -#: ../qml/pages/settings/ImportGitClone.qml:78 +#: ../qml/pages/settings/ImportGitClone.qml:80 msgid "An error occured during git clone !" msgstr "" -#: ../qml/pages/settings/ImportGitClone.qml:85 -#: ../qml/pages/settings/ImportZip.qml:89 +#: ../qml/pages/settings/ImportGitClone.qml:89 +#: ../qml/pages/settings/ImportZip.qml:82 msgid "Password store sucessfully imported !" msgstr "" -#: ../qml/pages/settings/ImportKeyFile.qml:17 -msgid "GPG Key Import" +#: ../qml/pages/settings/ImportGitClone.qml:101 +msgid "Git Clone Import" msgstr "" -#: ../qml/pages/settings/ImportKeyFile.qml:69 +#: ../qml/pages/settings/ImportKeyFile.qml:57 msgid "Key import failed !" msgstr "" -#: ../qml/pages/settings/ImportKeyFile.qml:76 +#: ../qml/pages/settings/ImportKeyFile.qml:66 msgid "Key successfully imported !" msgstr "" -#: ../qml/pages/settings/ImportZip.qml:17 -msgid "Zip Password Store Import" +#: ../qml/pages/settings/ImportKeyFile.qml:77 +msgid "GPG Key Import" msgstr "" -#: ../qml/pages/settings/ImportZip.qml:72 +#: ../qml/pages/settings/ImportZip.qml:61 msgid "" "Importing a new zip will delete
any existing password store!
Continue ?" msgstr "" -#: ../qml/pages/settings/ImportZip.qml:82 +#: ../qml/pages/settings/ImportZip.qml:73 msgid "Password store import failed !" msgstr "" -#: ../qml/pages/settings/InfoKeys.qml:16 -msgid "Info Keys" +#: ../qml/pages/settings/ImportZip.qml:94 +msgid "Zip Password Store Import" msgstr "" -#: ../qml/pages/settings/InfoKeys.qml:44 +#: ../qml/pages/settings/InfoKeys.qml:40 msgid "Key id : %1" msgstr "" -#: ../qml/pages/settings/InfoKeys.qml:49 +#: ../qml/pages/settings/InfoKeys.qml:46 msgid "Delete this key" msgstr "" -#: ../qml/pages/settings/InfoKeys.qml:68 +#: ../qml/pages/settings/InfoKeys.qml:67 msgid "You're are about to delete
%1
Continue ?" msgstr "" -#: ../qml/pages/settings/InfoKeys.qml:71 +#: ../qml/pages/settings/InfoKeys.qml:68 msgid "%1
will be definitively removed.
Continue ?" msgstr "" -#: ../qml/pages/settings/InfoKeys.qml:87 +#: ../qml/pages/settings/InfoKeys.qml:84 msgid "Key removal failed !" msgstr "" -#: ../qml/pages/settings/InfoKeys.qml:94 +#: ../qml/pages/settings/InfoKeys.qml:93 msgid "Key successfully deleted !" msgstr "" -#: ../qml/pages/settings/Settings.qml:28 +#: ../qml/pages/settings/InfoKeys.qml:104 +msgid "Info Keys" +msgstr "" + +#: ../qml/pages/settings/Settings.qml:23 msgid "GPG" msgstr "" -#: ../qml/pages/settings/Settings.qml:32 +#: ../qml/pages/settings/Settings.qml:28 msgid "Import a GPG key file" msgstr "" -#: ../qml/pages/settings/Settings.qml:36 +#: ../qml/pages/settings/Settings.qml:33 msgid "Show GPG keys" msgstr "" -#: ../qml/pages/settings/Settings.qml:43 +#: ../qml/pages/settings/Settings.qml:41 msgid "Password Store" msgstr "" -#: ../qml/pages/settings/Settings.qml:47 +#: ../qml/pages/settings/Settings.qml:46 msgid "Import a Password Store using Git" msgstr "" diff --git a/tests/assets/archive.zip b/tests/assets/archive.zip new file mode 100644 index 0000000000000000000000000000000000000000..451c772055ef77a3477037aa1a467dbf3fe8c1ef GIT binary patch literal 1072 zcmWIWW@h1H0D<$fwW7cbD8bJl!%&b|TwI=Cl%iW)l3$dn9~#2R!0ejdm=40F72FJr zEH9WD7{EjT+@PyKgS_7**DePd1j6E&29=~1m*}Mzq=O9%1R55BX<$nn^Y2>^?~0wX z$Q5E_cTi1J?wQ$iXlK&}arv`(;r-EtKh}0e2;E{;yJx57>z`n7?U4g-e)l8|!M8Jl zCN6K$7T5jWba$tMx@45cqZP}yopJq@_WH2bPCurKgYq{fTYS3W%E-wiF!@$vxc(d) zF^*=GVLI^N~ zxDaL^MT;C^OtV2czy=!v!_pEnJQ0Q&01aE)xa=4|(2*c4i)ol%dS*#tNl8&=QYkR5 zz{W}g-3r2J?$rYMNg*XOEzK6l06LkGNsbv;ijn}@1_A;MZyiB2M*3ofq%Sl(kPXF5 zT`)r#7?w18Vj7A_Ye2(6X$_Czm{ABZoDpd3l14`$h2~;-gaXaR5}C*j$BaT`htI_{ u8xo;FgFz9B$I+P4iR|cCm8HLpY!VJ&7|YYc5m3SW1-$l>n8n4ABYo0cb$t&xC;)*P;^2{02MK_;$cyhaLU-rz1Iq_R$Lqh@*i;ERP zQj1FzY)VTCfED^ED# zW3S8OjV2; zruGPFPLDor`Ldtk_tym9VpoG?iL)mQ`99v7Tkol^mZoj=?U~ywQ#NU(=co1O-V*7k zW03%clNy0=;(>${a$x*g#qi&M|Dt)3%eL&zagz9_{E)ZmVe_;b_8R4KA6;K-ygkIU ohv9z;$7JV&a(Na3D;=A!OqeelvC(MCb!B&MO`0@ o(R+-ݹ 'ZH⨧EfJNxؓ8E ځW/<-7# oJd7^?H4H9`kdwgd9ឣx \ No newline at end of file diff --git a/tests/plugins/CMakeLists.txt b/tests/plugins/CMakeLists.txt new file mode 100644 index 0000000..8f532e1 --- /dev/null +++ b/tests/plugins/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(TestsUtils) diff --git a/tests/plugins/TestsUtils/CMakeLists.txt b/tests/plugins/TestsUtils/CMakeLists.txt new file mode 100644 index 0000000..f475fff --- /dev/null +++ b/tests/plugins/TestsUtils/CMakeLists.txt @@ -0,0 +1,29 @@ +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +set(PLUGIN "TestsUtils") + +set( + SRC + plugin.cpp + utils.cpp +) + +set(CMAKE_AUTOMOC ON) + +execute_process( + COMMAND dpkg-architecture -qDEB_HOST_MULTIARCH + OUTPUT_VARIABLE ARCH_TRIPLET + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +if(ARCH_TRIPLET STREQUAL "") + set(ARCH_TRIPLET x86_64-linux-gnu) +endif() + +add_library(${PLUGIN} MODULE ${SRC}) +set_target_properties(${PLUGIN} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGIN}) +qt5_use_modules(${PLUGIN} Qml Quick DBus) + +set(QT_IMPORTS_DIR "/lib/${ARCH_TRIPLET}") + +install(TARGETS ${PLUGIN} DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN}/) +install(FILES qmldir DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN}/) diff --git a/tests/plugins/TestsUtils/plugin.cpp b/tests/plugins/TestsUtils/plugin.cpp new file mode 100644 index 0000000..5a7f324 --- /dev/null +++ b/tests/plugins/TestsUtils/plugin.cpp @@ -0,0 +1,10 @@ +#include + +#include "plugin.h" +#include "utils.h" + +void TestsUtilsPlugin::registerTypes(const char *uri) +{ + //@uri TestUtils + qmlRegisterSingletonType(uri, 1, 0, "TestUtils", [](QQmlEngine *, QJSEngine *) -> QObject * { return new TestsUtils; }); +} diff --git a/tests/plugins/TestsUtils/plugin.h b/tests/plugins/TestsUtils/plugin.h new file mode 100644 index 0000000..b026f2d --- /dev/null +++ b/tests/plugins/TestsUtils/plugin.h @@ -0,0 +1,16 @@ +#ifndef TESTSUTILSPLUGIN_H +#define TESTSUTILSPLUGIN_H + +#include + +class TestsUtilsPlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID + "org.qt-project.Qt.QQmlExtensionInterface") + +public: + void registerTypes(const char *uri) override; +}; + +#endif diff --git a/tests/plugins/TestsUtils/qmldir b/tests/plugins/TestsUtils/qmldir new file mode 100644 index 0000000..b129367 --- /dev/null +++ b/tests/plugins/TestsUtils/qmldir @@ -0,0 +1,2 @@ +module TestUtils +plugin TestUtils diff --git a/tests/plugins/TestsUtils/utils.cpp b/tests/plugins/TestsUtils/utils.cpp new file mode 100644 index 0000000..47495c5 --- /dev/null +++ b/tests/plugins/TestsUtils/utils.cpp @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include + +#include "utils.h" + + +QString TestsUtils::getTempPath() { + qFatal("yp"); + // Get the system's temporary directory + QString tempDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); + qDebug() << "TempDir : " << tempDir; + + // Generate a unique UUID + QString uuid = QUuid::createUuid().toString(QUuid::WithoutBraces); + + // Create a new directory using the generated UUID + QString newTempDir = tempDir + "/" + uuid; + + QDir dir; + if (!dir.exists(newTempDir)) { + // Create the directory + if (dir.mkpath(newTempDir)) { + return newTempDir; // Return the path if successful + } else { + return "Failed to create directory"; // Return an error message + } + } else { + return newTempDir; // If the directory already exists, return its path + } +} + + + diff --git a/tests/plugins/TestsUtils/utils.h b/tests/plugins/TestsUtils/utils.h new file mode 100644 index 0000000..ceb0ceb --- /dev/null +++ b/tests/plugins/TestsUtils/utils.h @@ -0,0 +1,19 @@ +#ifndef TESTSUTILS_H +#define TESTSUTILS_H + +#include +#include +#include + +class TestsUtils : public QObject +{ + Q_OBJECT + +public: + TestsUtils() = default; + ~TestsUtils() override = default; + + Q_INVOKABLE QString getTempPath(); +}; + +#endif diff --git a/tests/unit/tst_git.qml b/tests/unit/tst_git.qml new file mode 100644 index 0000000..542304b --- /dev/null +++ b/tests/unit/tst_git.qml @@ -0,0 +1,12 @@ +import QtQuick 2.9 +import QtTest 1.2 +import Git 1.0 + +TestCase { + name: "git" + + function test_git_clone() { + + verify(Git.clone("","")); + } +} diff --git a/tests/unit/tst_pass.qml b/tests/unit/tst_pass.qml new file mode 100644 index 0000000..542304b --- /dev/null +++ b/tests/unit/tst_pass.qml @@ -0,0 +1,12 @@ +import QtQuick 2.9 +import QtTest 1.2 +import Git 1.0 + +TestCase { + name: "git" + + function test_git_clone() { + + verify(Git.clone("","")); + } +} diff --git a/tests/unit/tst_utils.qml b/tests/unit/tst_utils.qml new file mode 100644 index 0000000..25e5295 --- /dev/null +++ b/tests/unit/tst_utils.qml @@ -0,0 +1,15 @@ +import QtQuick 2.9 +import QtTest 1.2 +import TestUtils 1.0 +import Utils 1.0 + +TestCase { + name: "utils" + + function test_unzip() { + var tempPath = TestUtils.getTempPath() + "/password-store"; + var zipUrl = Qt.resolvedUrl("../assets/archive.zip"); + var r = Utils.unzip(zipUrl, tempPath) + verify(r, "Unzip return an error %1".arg(zipUrl)) + } +}