summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDirk-Jan C. Binnema <djcb@djcbsoftware.nl>2022-06-28 23:24:22 +0300
committerDirk-Jan C. Binnema <djcb@djcbsoftware.nl>2022-06-29 07:50:16 +0300
commit23ac71e6a70c86e76ae376f2cafcc97567ae044c (patch)
tree5954e8115745d7da8b1ab1912f74cfa18be98fa7
parenteb790727ed3a7bf101fc133b84ccf863f98bed31 (diff)
maildir: add tests for maildir_link / maildir_clear_links
-rw-r--r--lib/mu-maildir.cc30
-rw-r--r--lib/mu-maildir.hh7
-rw-r--r--lib/tests/test-mu-maildir.cc48
3 files changed, 68 insertions, 17 deletions
diff --git a/lib/mu-maildir.cc b/lib/mu-maildir.cc
index 1b19176..1045ca1 100644
--- a/lib/mu-maildir.cc
+++ b/lib/mu-maildir.cc
@@ -147,7 +147,8 @@ check_subdir(const std::string& src, bool& in_cur)
}
static Mu::Result<std::string>
-get_target_fullpath(const std::string& src, const std::string& targetpath)
+get_target_fullpath(const std::string& src, const std::string& targetpath,
+ bool unique_names)
{
bool in_cur{};
if (auto&& res = check_subdir(src, in_cur); !res)
@@ -159,21 +160,30 @@ get_target_fullpath(const std::string& src, const std::string& targetpath)
* including a hash of the srcname in the targetname. This helps if
* there are copies of a message (which all have the same basename)
*/
- auto targetfullpath = format("%s%c%s%c%u_%s",
- targetpath.c_str(),
- G_DIR_SEPARATOR, in_cur ? "cur" : "new",
- G_DIR_SEPARATOR,
- g_str_hash(src.c_str()),
- srcfile);
+ std::string fulltargetpath;
+ if (unique_names)
+ fulltargetpath = format("%s%c%s%c%u_%s",
+ targetpath.c_str(),
+ G_DIR_SEPARATOR, in_cur ? "cur" : "new",
+ G_DIR_SEPARATOR,
+ g_str_hash(src.c_str()),
+ srcfile);
+ else
+ fulltargetpath = format("%s%c%s%c%s",
+ targetpath.c_str(),
+ G_DIR_SEPARATOR, in_cur ? "cur" : "new",
+ G_DIR_SEPARATOR,
+ srcfile);
g_free(srcfile);
- return targetfullpath;
+ return fulltargetpath;
}
Result<void>
-Mu::maildir_link(const std::string& src, const std::string& targetpath)
+Mu::maildir_link(const std::string& src, const std::string& targetpath,
+ bool unique_names)
{
- auto path_res{get_target_fullpath(src, targetpath)};
+ auto path_res{get_target_fullpath(src, targetpath, unique_names)};
if (!path_res)
return Err(std::move(path_res.error()));
diff --git a/lib/mu-maildir.hh b/lib/mu-maildir.hh
index f4f38d3..7976b04 100644
--- a/lib/mu-maildir.hh
+++ b/lib/mu-maildir.hh
@@ -48,7 +48,7 @@ namespace Mu {
* @return a valid result (!!result) or an Error
*/
Result<void> maildir_mkdir(const std::string& path, mode_t mode=0700,
- bool noindex=false);
+ bool noindex=false);
/**
* Create a symbolic link to a mail message
@@ -57,10 +57,13 @@ Result<void> maildir_mkdir(const std::string& path, mode_t mode=0700,
* @param targetpath the path to the target maildir; ie., *not*
* MyMaildir/cur, but just MyMaildir/. The function will figure out
* the correct subdir then.
+ * @param unique_names whether to create unique names; should be true unless
+ * for tests.
*
* @return a valid result (!!result) or an Error
*/
-Result<void> maildir_link(const std::string& src, const std::string& targetpath);
+Result<void> maildir_link(const std::string& src, const std::string& targetpath,
+ bool unique_names=true);
/**
* Recursively delete all the symbolic links in a directory tree
diff --git a/lib/tests/test-mu-maildir.cc b/lib/tests/test-mu-maildir.cc
index 364e9cd..c8f0690 100644
--- a/lib/tests/test-mu-maildir.cc
+++ b/lib/tests/test-mu-maildir.cc
@@ -24,6 +24,7 @@
#include <unistd.h>
#include <string.h>
#include <vector>
+#include <fstream>
#include "test-mu-common.hh"
#include "mu-maildir.hh"
@@ -454,6 +455,47 @@ test_maildir_from_path(void)
}
}
+static void
+test_maildir_link()
+{
+ TempDir tmpdir{false};
+
+ g_message("%s", tmpdir.path().c_str());
+
+ g_assert_true(!!maildir_mkdir(tmpdir.path() + "/foo"));
+ g_assert_true(!!maildir_mkdir(tmpdir.path() + "/bar"));
+
+ const auto srcpath1 = tmpdir.path() + "/foo/cur/msg1";
+ const auto srcpath2 = tmpdir.path() + "/foo/new/msg2";
+
+ {
+ std::ofstream stream(srcpath1);
+ stream.write("cur", 3);
+ g_assert_true(stream.good());
+ stream.close();
+ }
+
+ {
+ std::ofstream stream(srcpath2);
+ stream.write("new", 3);
+ g_assert_true(stream.good());
+ stream.close();
+ }
+
+ g_assert_true(!!maildir_link(srcpath1, tmpdir.path() + "/bar", false));
+ g_assert_true(!!maildir_link(srcpath2, tmpdir.path() + "/bar", false));
+
+ const auto dstpath1 = tmpdir.path() + "/bar/cur/msg1";
+ const auto dstpath2 = tmpdir.path() + "/bar/new/msg2";
+
+ g_assert_true(g_access(dstpath1.c_str(), F_OK) == 0);
+ g_assert_true(g_access(dstpath2.c_str(), F_OK) == 0);
+
+ g_assert_true(!!maildir_clear_links(tmpdir.path() + "/bar"));
+ g_assert_false(g_access(dstpath1.c_str(), F_OK) == 0);
+ g_assert_false(g_access(dstpath2.c_str(), F_OK) == 0);
+}
+
int
main(int argc, char* argv[])
{
@@ -479,11 +521,7 @@ main(int argc, char* argv[])
g_test_add_func("/mu-maildir/mu-maildir-from-path",
test_maildir_from_path);
- g_log_set_handler(
- NULL,
- (GLogLevelFlags)(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION),
- (GLogFunc)black_hole,
- NULL);
+ g_test_add_func("/mu-maildir/mu-maildir-link", test_maildir_link);
return g_test_run();
}