diff --git a/cmake/Testing.cmake b/cmake/Testing.cmake
index 749512fb6..0d9988806 100644
--- a/cmake/Testing.cmake
+++ b/cmake/Testing.cmake
@@ -34,15 +34,16 @@ function(auto_test subsystem module extra_deps)
COMMAND ${TEST_CROSSCOMPILING_EMULATOR} test_${module})
endfunction()
-auto_test(core core ${${PROJECT_NAME}_RESOURCES})
+auto_test(core core "${${PROJECT_NAME}_RESOURCES}")
auto_test(core contactid "")
auto_test(core toxid "")
auto_test(core toxstring "")
auto_test(chatlog textformatter "")
-auto_test(net bsu ${${PROJECT_NAME}_RESOURCES}) # needs nodes list
+auto_test(net bsu "${${PROJECT_NAME}_RESOURCES}") # needs nodes list
auto_test(persistence paths "")
auto_test(persistence dbschema "")
auto_test(persistence offlinemsgengine "")
+auto_test(persistence smileypack "${${PROJECT_NAME}_RESOURCES}") # needs emojione
auto_test(model friendmessagedispatcher "")
auto_test(model groupmessagedispatcher "")
auto_test(model messageprocessor "")
diff --git a/test/persistence/smileypack_test.cpp b/test/persistence/smileypack_test.cpp
new file mode 100644
index 000000000..477737d8e
--- /dev/null
+++ b/test/persistence/smileypack_test.cpp
@@ -0,0 +1,117 @@
+/*
+ Copyright Β© 2021 by The qTox Project Contributors
+
+ This file is part of qTox, a Qt-based graphical interface for Tox.
+
+ qTox is libre software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ qTox is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with qTox. If not, see .
+*/
+
+#include "src/persistence/smileypack.h"
+
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+
+QString getAsRichText(const QString& key);
+
+class TestSmileyPack : public QObject
+{
+ Q_OBJECT
+public:
+ TestSmileyPack();
+
+private slots:
+ void testSmilifySingleCharEmoji();
+ void testSmilifyMultiCharEmoji();
+ void testSmilifyAsciiEmoticon();
+private:
+ std::unique_ptr app;
+};
+
+TestSmileyPack::TestSmileyPack()
+{
+ static char arg1[]{"QToxSmileyPackTestApp"};
+ static char arg2[]{"-platform"};
+ static char arg3[]{"offscreen"};
+ static char* qtTestAppArgv[] = {arg1, arg2, arg3};
+ static int qtTestAppArgc = 3;
+
+ app = std::unique_ptr(new QGuiApplication(qtTestAppArgc, qtTestAppArgv));
+}
+
+/**
+ * @brief Test that single-character emojis (non-ascii) are correctly smilified
+ */
+void TestSmileyPack::testSmilifySingleCharEmoji()
+{
+ auto& smileyPack = SmileyPack::getInstance();
+
+ auto result = smileyPack.smileyfied("π");
+ QVERIFY(result == getAsRichText("π"));
+
+ result = smileyPack.smileyfied("SomeπLetters");
+ QVERIFY(result == "Some" + getAsRichText("π") + "Letters");
+}
+
+/**
+ * @brief Test that multi-character emojis (non-ascii) are correctly smilified
+ * and not incorrectly matched against single-char counterparts
+ */
+void TestSmileyPack::testSmilifyMultiCharEmoji()
+{
+ auto& smileyPack = SmileyPack::getInstance();
+
+ auto result = smileyPack.smileyfied("π¬π§");
+ QVERIFY(result == getAsRichText("π¬π§"));
+
+ result = smileyPack.smileyfied("Someπ¬π§Letters");
+ QVERIFY(result == "Some" + getAsRichText("π¬π§") + "Letters");
+
+ // This verifies that multi-char emojis are not accidentally
+ // considered a multichar ascii smiley
+ result = smileyPack.smileyfied("π«π·π¬π§");
+ QVERIFY(result == getAsRichText("π«π·") + getAsRichText("π¬π§"));
+}
+
+
+/**
+ * @brief Test that single character emojis (non-ascii) are correctly smilified
+ * and not when surrounded by non-punctuation and non-whitespace chars
+ */
+void TestSmileyPack::testSmilifyAsciiEmoticon()
+{
+ auto& smileyPack = SmileyPack::getInstance();
+
+ auto result = smileyPack.smileyfied(":-)");
+ QVERIFY(result == getAsRichText(":-)"));
+
+ constexpr auto testMsg = "Some:-)Letters";
+ result = smileyPack.smileyfied(testMsg);
+
+ // Nothing has changed. Ascii smileys are only considered
+ // when they are surrounded by white space
+ QVERIFY(result == testMsg);
+
+ result = smileyPack.smileyfied(" :-) ");
+ QVERIFY(result == " " + getAsRichText(":-)") + " ");
+}
+
+
+QTEST_GUILESS_MAIN(TestSmileyPack)
+#include "smileypack_test.moc"