/** @short Check that the STATUS processing does not break offline "sync" */
void OfflineTest::testStatusVsExistsCached()
{
    QString mailbox = QLatin1String("a");

    // Push the data to the cache
    existsA = 10;
    uidNextA = 11;
    uidValidityA = 666;
    SyncState sync;
    sync.setExists(existsA);
    sync.setUidValidity(uidValidityA);
    sync.setUidNext(uidNextA);
    for (uint i = 1; i <= existsA; ++i)
        uidMapA << i;
    model->cache()->setMailboxSyncState(mailbox, sync);
    model->cache()->setUidMapping(mailbox, uidMapA);

    // Request the STATUS command to see how many messages are in there. This is not a synchronization, though
    // -- Trojita is *not* opening that mailbox, so the previously cached data remain.
    QCOMPARE(idxA.data(RoleTotalMessageCount).toInt(), 0);
    cClient(t.mk("STATUS a (MESSAGES UNSEEN RECENT)\r\n"));
    cServer("* STATUS a (MESSAGES 42 UNSEEN 2 RECENT 3)\r\n" + t.last("OK status\r\n"));
    QCOMPARE(idxA.data(RoleTotalMessageCount).toInt(), 42);
    LibMailboxSync::setModelNetworkPolicy(model, NETWORK_OFFLINE);
    cClient(t.mk("LOGOUT\r\n"));
    cServer(t.last("OK logged out\r\n") + "* BYE see ya\r\n");
    model->resyncMailbox(idxA);
    for (int i = 0; i < 10; ++i)
        QCoreApplication::processEvents();
    QCOMPARE(model->rowCount(msgListA), static_cast<int>(existsA));
    helperVerifyUidMapA();
    helperCheckCache();
}
/** @short Check that cached mailboxes do not send away STATUS when they are going to be immediately replaced anyway */
void ImapModelListChildMailboxesTest::testNoStatusForCachedItems()
{
    using namespace Imap::Mailbox;

    // Remember two mailboxes
    model->cache()->setChildMailboxes(QString(), QList<MailboxMetadata>()
                                      << MailboxMetadata(QStringLiteral("a"), QStringLiteral("."), QStringList())
                                      << MailboxMetadata(QStringLiteral("b"), QStringLiteral("."), QStringList())
                                      );
    // ... and the numbers for the first of them
    SyncState s;
    s.setExists(10);
    s.setRecent(1);
    s.setUnSeenCount(2);
    QVERIFY(s.isUsableForNumbers());
    model->cache()->setMailboxSyncState(QStringLiteral("b"), s);

    // touch the network
    QCOMPARE(model->rowCount(QModelIndex()), 1);
    cClient(t.mk("LIST \"\" \"%\"\r\n"));
    // ...but the data gets refreshed from cache immediately
    QCOMPARE(model->rowCount(QModelIndex()), 3);

    // just settings up indexes
    idxA = model->index(1, 0, QModelIndex());
    QVERIFY(idxA.isValid());
    QCOMPARE(idxA.data(RoleMailboxName).toString(), QString::fromUtf8("a"));
    idxB = model->index(2, 0, QModelIndex());
    QVERIFY(idxB.isValid());
    QCOMPARE(idxB.data(RoleMailboxName).toString(), QString::fromUtf8("b"));

    // Request message counts; this should not lead to network activity even though the actual number
    // is not stored in the cache for mailbox "a", simply because the whole mailbox will get replaced
    // after the LIST finishes anyway
    QCOMPARE(idxA.data(RoleTotalMessageCount), QVariant());
    QCOMPARE(idxA.data(RoleMailboxNumbersFetched).toBool(), false);
    QCOMPARE(idxB.data(RoleTotalMessageCount).toInt(), 10);
    QCOMPARE(idxB.data(RoleMailboxNumbersFetched).toBool(), false);
    cEmpty();

    cServer("* LIST (\\HasNoChildren) \".\" a\r\n"
            "* LIST (\\HasNoChildren) \".\" b\r\n"
            + t.last("OK listed\r\n"));
    cEmpty();

    // The mailboxes are replaced now -> rebuild the indexes
    QVERIFY(!idxA.isValid());
    QVERIFY(!idxB.isValid());
    idxA = model->index(1, 0, QModelIndex());
    QVERIFY(idxA.isValid());
    QCOMPARE(idxA.data(RoleMailboxName).toString(), QString::fromUtf8("a"));
    idxB = model->index(2, 0, QModelIndex());
    QVERIFY(idxB.isValid());
    QCOMPARE(idxB.data(RoleMailboxName).toString(), QString::fromUtf8("b"));

    // Ask for the numbers again
    QCOMPARE(idxA.data(RoleTotalMessageCount), QVariant());
    QCOMPARE(idxB.data(RoleTotalMessageCount), QVariant());
    QByteArray c1 = t.mk("STATUS a (MESSAGES UNSEEN RECENT)\r\n");
    QByteArray r1 = t.last("OK status\r\n");
    QByteArray c2 = t.mk("STATUS b (MESSAGES UNSEEN RECENT)\r\n");
    QByteArray r2 = t.last("OK status\r\n");
    cClient(c1 + c2);
    cServer("* STATUS a (MESSAGES 1 RECENT 2 UNSEEN 3)\r\n"
            "* STATUS b (MESSAGES 666 RECENT 33 UNSEEN 2)\r\n");
    QCOMPARE(idxA.data(RoleTotalMessageCount).toInt(), 1);
    QCOMPARE(idxA.data(RoleMailboxNumbersFetched).toBool(), true);
    QCOMPARE(idxB.data(RoleTotalMessageCount).toInt(), 666);
    QCOMPARE(idxB.data(RoleMailboxNumbersFetched).toBool(), true);
    QCOMPARE(model->cache()->mailboxSyncState(QLatin1String("a")).unSeenCount(), 3u);
    QCOMPARE(model->cache()->mailboxSyncState(QLatin1String("a")).recent(), 2u);
    // the "EXISTS" is missing, though
    QVERIFY(!model->cache()->mailboxSyncState(QLatin1String("a")).isUsableForNumbers());
    QCOMPARE(model->cache()->mailboxSyncState(QLatin1String("b")).unSeenCount(), 2u);
    QCOMPARE(model->cache()->mailboxSyncState(QLatin1String("b")).recent(), 33u);
    // The mailbox state for mailbox "b" must be preserved
    QCOMPARE(model->cache()->mailboxSyncState(QLatin1String("b")).exists(), 10u);
    QVERIFY(model->cache()->mailboxSyncState(QLatin1String("b")).isUsableForNumbers());
    cServer(r2 + r1);
    cEmpty();
}