aboutsummaryrefslogblamecommitdiffstats
path: root/camel/tests/folder/test3.c
blob: ecd0a46fe76248c467ad9adbc675d1f478bc5b14 (plain) (tree)

































































































































































































































































































                                                                                                                            
/* folder/index testing */

#include "camel-test.h"
#include "messages.h"
#include "folders.h"

#include <camel/camel-exception.h>
#include <camel/camel-service.h>
#include <camel/camel-session.h>
#include <camel/camel-store.h>

#include <camel/camel-folder.h>
#include <camel/camel-folder-summary.h>
#include <camel/camel-mime-message.h>

/* god, who designed this horrid interface */
static char *auth_callback(CamelAuthCallbackMode mode,
               char *data, gboolean secret,
               CamelService *service, char *item,
               CamelException *ex)
{
    return NULL;
}


static void
test_folder_search_sub(CamelFolder *folder, const char *expr, int expected)
{
    CamelException *ex = camel_exception_new();
    GPtrArray *uids;
    GHashTable *hash;
    int i;

    uids = camel_folder_search_by_expression(folder, expr, ex);
    check(uids != NULL);
    check(uids->len == expected);
    check_msg(!camel_exception_is_set(ex), "%s", camel_exception_get_description(ex));

    /* check the uid's are actually unique, too */
    hash = g_hash_table_new(g_str_hash, g_str_equal);
    for (i=0;uids->len;i++) {
        check(g_hash_table_lookup(hash, uids->pdata[i]) == NULL);
        g_hash_table_insert(hash, uids->pdata[i], uids->pdata[i]);
    }
    g_hash_table_destroy(hash);

    camel_folder_search_free(folder, uids);

    camel_exception_free(ex);
}

static void
test_folder_search(CamelFolder *folder, const char *expr, int expected)
{
    char *matchall;

    push("Testing search: %s", expr);
    test_folder_search_sub(folder, expr, expected);
    pull();

    matchall = g_strdup_printf("(match-all %s)", expr);
    push("Testing search: %s", matchall);
    test_folder_search_sub(folder, matchall, expected);
    test_free(matchall);
    pull();
}

#define ARRAY_LEN(x) (sizeof(x)/sizeof(x[0]))

static char *stores[] = {
    "mbox:///tmp/camel-test/mbox",
    "mh:///tmp/camel-test/mh",
    "maildir:///tmp/camel-test/maildir"
};

int main(int argc, char **argv)
{
    CamelSession *session;
    CamelStore *store;
    CamelException *ex;
    CamelFolder *folder;
    CamelMimeMessage *msg;
    int i, j;
    int indexed;
    GPtrArray *uids;

    ex = camel_exception_new();

    camel_test_init(argc, argv);

    session = camel_session_new("/tmp/camel-test", auth_callback, NULL, NULL);

    /* todo: cross-check everything with folder_info checks as well */
    /* todo: work out how to do imap/pop/nntp tests */

    /* we iterate over all stores we want to test, with indexing or indexing turned on or off */
    for (i=0;i<ARRAY_LEN(stores);i++) {
        char *name = stores[i];
        for (indexed = 0;indexed<2;indexed++) {
            char *what = g_strdup_printf("folder search: %s (%sindexed)", name, indexed?"":"non-");
            int flags;

            camel_test_start(what);
            test_free(what);

            push("getting store");
            store = camel_session_get_store(session, stores[i], ex);
            check_msg(!camel_exception_is_set(ex), "getting store: %s", camel_exception_get_description(ex));
            check(store != NULL);
            pull();

            push("creating %sindexed folder", indexed?"":"non-");
            if (indexed)
                flags = CAMEL_STORE_FOLDER_CREATE|CAMEL_STORE_FOLDER_BODY_INDEX;
            else
                flags = CAMEL_STORE_FOLDER_CREATE;
            folder = camel_store_get_folder(store, "testbox", flags, ex);
            check_msg(!camel_exception_is_set(ex), "%s", camel_exception_get_description(ex));
            check(folder != NULL);

            /* we need an empty folder for this to work */
            test_folder_counts(folder, 0, 0);
            pull();

            /* append a bunch of messages with specific content */
            push("appending 100 test messages");
            for (j=0;j<100;j++) {
                char *content, *subject;

                push("creating test message");
                msg = test_message_create_simple();
                content = g_strdup_printf("data%d content\n", j);
                test_message_set_content_simple((CamelMimePart *)msg, 0, "text/plain",
                                content, strlen(content));
                test_free(content);
                subject = g_strdup_printf("Test%d message%d subject", j, 100-j);
                camel_mime_message_set_subject(msg, subject);

                camel_mime_message_set_date(msg, j*60*24, 0);

                pull();

                push("appending simple message %d", j);
                camel_folder_append_message(folder, msg, NULL, ex);
                check_msg(!camel_exception_is_set(ex), "%s", camel_exception_get_description(ex));
                pull();

                test_free(subject);

                check_unref(msg, 1);
            }
            pull();

            push("Setting up some flags &c");
            uids = camel_folder_get_uids(folder);
            check(uids->len == 100);
            for (j=0;j<100;j++) {
                char *uid = uids->pdata[j];

                if ((j/13)*13 == j) {
                    camel_folder_set_message_user_flag(folder, uid, "every13", TRUE);
                }
                if ((j/17)*17 == j) {
                    camel_folder_set_message_user_flag(folder, uid, "every17", TRUE);
                }
                if ((j/7)*7 == j) {
                    char *tag = g_strdup_printf("7tag%d", j/7);
                    camel_folder_set_message_user_tag(folder, uid, "every7", tag);
                    test_free(tag);
                }
                if ((j/11)*11 == j) {
                    camel_folder_set_message_user_tag(folder, uid, "every11", "11tag");
                }
            }
            camel_folder_free_uids(folder, uids);
            pull();

            /* should try invalid search strings too */

            /* try some searches */
            push("performing searches");
            test_folder_search(folder, "(header-contains \"subject\" \"subject\")", 100);
            test_folder_search(folder, "(header-contains \"subject\" \"Subject\")", 100);

            test_folder_search(folder, "(body-contains \"content\")", 100);
            test_folder_search(folder, "(body-contains \"Content\")", 100);

            test_folder_search(folder, "(user-flag \"every7\")", 0);
            test_folder_search(folder, "(user-flag \"every13\")", 100/13);
            test_folder_search(folder, "(= \"7tag1\" (user-tag \"every7\"))", 1);
            test_folder_search(folder, "(= \"11tag\" (user-tag \"every11\"))", 100/11);

            test_folder_search(folder, "(user-flag \"every13\" \"every17\")", 100/13 + 100/17);
            test_folder_search(folder, "(or (user-flag \"every13\") (user-flag \"every17\"))", 100/13 + 100/17);
            test_folder_search(folder, "(and (user-flag \"every13\") (user-flag \"every17\"))", 0);

            test_folder_search(folder, "(and (header-contains \"subject\" \"Test1\")"
                       "(header-contains \"subject\" \"Test2\"))", 0);
            test_folder_search(folder, "(and (header-contains \"subject\" \"Test1\")"
                       "(header-contains \"subject\" \"subject\"))", 1);
            test_folder_search(folder, "(and (header-contains \"subject\" \"Test1\")"
                       "(header-contains \"subject\" \"message99\"))", 1);

            test_folder_search(folder, "(or (header-contains \"subject\" \"Test1\")"
                       "(header-contains \"subject\" \"Test2\"))", 2);
            test_folder_search(folder, "(or (header-contains \"subject\" \"Test1\")"
                       "(header-contains \"subject\" \"subject\"))", 100);
            test_folder_search(folder, "(or (header-contains \"subject\" \"Test1\")"
                       "(header-contains \"subject\" \"message99\"))", 1);

            /* 7200 is 24*60*50 == half the 'sent date' of the messages */
            test_folder_search(folder, "(> 7200 (get-sent-date))", 49);
            test_folder_search(folder, "(< 7200 (get-sent-date))", 49);
            test_folder_search(folder, "(= 7200 (get-sent-date))", 1);
            test_folder_search(folder, "(= 7201 (get-sent-date))", 0);

            test_folder_search(folder, "(and (user-flag \"every17\") (< 7200 (get-sent-date)))", 49/17);
            test_folder_search(folder, "(and (user-flag \"every17\") (> 7200 (get-sent-date)))", 49/17-1);
            test_folder_search(folder, "(and (user-flag \"every13\") (< 7200 (get-sent-date)))", 49/13);
            test_folder_search(folder, "(and (user-flag \"every13\") (> 7200 (get-sent-date)))", 49/13-1);

            test_folder_search(folder, "(or (user-flag \"every17\") (< 7200 (get-sent-date)))", 49);
            test_folder_search(folder, "(or (user-flag \"every17\") (> 7200 (get-sent-date)))", 49);
            test_folder_search(folder, "(or (user-flag \"every13\") (< 7200 (get-sent-date)))", 49);
            test_folder_search(folder, "(or (user-flag \"every13\") (> 7200 (get-sent-date)))", 49);

            push("deleting every 2nd message & expunging");
            uids = camel_folder_get_uids(folder);
            check(uids->len == 100);
            for (j=0;j<uids->len;j++) {
                camel_folder_delete_message(folder, uids->pdata[j]);
            }

            push("searches after deletions, before sync");
            test_folder_search(folder, "(header-contains \"subject\" \"subject\")", 100);
            test_folder_search(folder, "(body-contains \"content\")", 100);
            pull();

            camel_folder_sync(folder, FALSE, ex);

            push("searches after sync, before expunge");
            test_folder_search(folder, "(header-contains \"subject\" \"subject\")", 100);
            test_folder_search(folder, "(body-contains \"content\")", 100);
            pull();

            camel_folder_expunge(folder, ex);
            check_msg(!camel_exception_is_set(ex), "%s", camel_exception_get_description(ex));
            camel_folder_free_uids(folder, uids);
            pull();

            /* more searches */
            push("searches after deletions");
            test_folder_search(folder, "(header-contains \"subject\" \"subject\")", 50);
            test_folder_search(folder, "(body-contains \"content\")", 50);
            pull();

            push("deleting remaining messages & expunging");
            uids = camel_folder_get_uids(folder);
            check(uids->len == 100);
            for (j=0;j<uids->len;j++) {
                camel_folder_delete_message(folder, uids->pdata[j]);
            }
            camel_folder_expunge(folder, ex);
            check_msg(!camel_exception_is_set(ex), "%s", camel_exception_get_description(ex));
            camel_folder_free_uids(folder, uids);
            pull();

            push("searches wtih no messages");
            test_folder_search(folder, "(header-contains \"subject\" \"subject\")", 0);
            test_folder_search(folder, "(body-contains \"content\")", 0);
            pull();

            check_unref(folder, 1);
            pull();

            push("deleting test folder, with no messages in it");
            camel_store_delete_folder(store, "testbox", ex);
            check_msg(!camel_exception_is_set(ex), "%s", camel_exception_get_description(ex));
            pull();

            camel_object_unref((CamelObject *)store);
            camel_test_end();
        }
    }

    camel_object_unref((CamelObject *)session);
    camel_exception_free(ex);

    return 0;
}