void ConversationModelTest::modifyEvent()
{
    ConversationModel model;
    model.enableContactChanges(false);
    watcher.setModel(&model);
    model.setQueryMode(EventModel::SyncQuery);
    QVERIFY(model.getEvents(group1.id()));

    Event event;
    /* modify invalid event */
    QVERIFY(!model.modifyEvent(event));

    QVERIFY(model.rowCount() > 0);

    int row = rand() % model.rowCount();
    event = model.event(model.index(row, 0));
    qDebug() << row << event.id() << event.freeText();
    event.setFreeText("modified event");
    QDateTime modified = event.lastModified();
    QVERIFY(model.modifyEvent(event));
    watcher.waitForSignals();
    QVERIFY(model.trackerIO().getEvent(event.id(), event));
    QCOMPARE(event.freeText(), QString("modified event"));

    QSKIP("Make nie:contentLastUpdated handling consistent", SkipSingle);
    event = model.event(model.index(row, 0));
    QCOMPARE(event.freeText(), QString("modified event"));
    QVERIFY(event.lastModified() > modified);
}
void ConversationModelTest::contacts()
{
    QFETCH(QString, localId);
    QFETCH(QString, remoteId);
    QFETCH(int, eventType);

    Group group;
    addTestGroup(group, localId, remoteId);

    ConversationModel model;
    Event::PropertySet p;
    p.insert(Event::ContactId);
    p.insert(Event::ContactName);
    model.setPropertyMask(p);

    model.enableContactChanges(false);
    watcher.setModel(&model);

    addTestEvent(model, (Event::EventType)eventType, Event::Inbound, localId,
                 group.id(), "text", false, false, QDateTime::currentDateTime(), remoteId);

    QVERIFY(model.getEvents(group.id()));
    QVERIFY(watcher.waitForModelReady());

    Event event;
    event = model.event(model.index(0, 0));
    QCOMPARE(event.contactId(), 0);

    QString noMatch = remoteId;
    noMatch += remoteId[1];

    int contactId1 = addTestContact("Really1Funny",
                   noMatch,
                   localId);

    QVERIFY(model.getEvents(group.id()));
    QVERIFY(watcher.waitForModelReady());

    event = model.event(model.index(0, 0));
    QCOMPARE(event.contactId(), 0);

    int contactId = addTestContact("ReallyUFunny", remoteId, localId);
    QTime timer;
    timer.start();
    while (timer.elapsed() < 1000)
        QCoreApplication::processEvents();
    QVERIFY(model.getEvents(group.id()));
    QVERIFY(watcher.waitForModelReady());

    event = model.event(model.index(0, 0));
    QCOMPARE(event.contactId(), contactId);
    QCOMPARE(event.contactName(), QString("ReallyUFunny"));

    deleteTestContact(contactId1);
    deleteTestContact(contactId);
}
void Util::exportSMS(QTextStream &out) {
    GroupModel groupModel;
    groupModel.enableContactChanges(false);
    groupModel.setQueryMode(EventModel::SyncQuery);

    groupModel.getGroups();

    EventModel eventModel;
    ConversationModel model;
    model.enableContactChanges(false);
    model.setQueryMode(EventModel::SyncQuery);
    for (int i = 0; i < groupModel.rowCount(); i++) {
        Group g = groupModel.group(groupModel.index(i, 0));

        model.getEvents(g.id());

        // the events got by getEvents is reversed-ordered
        for (int i = model.rowCount() - 1; i >= 0; i--) {
            Event event = model.event(model.index(i, 0));
            out << QString(event.remoteUid() % QChar(',') %
                                      QString::number(event.direction()) % QChar(',') %
                                      event.startTime().toLocalTime().toString(QString("yyyy-MM-dd hh:mm:ss")) % QChar(',') %
                                      QChar('"') % event.freeText().replace(QChar('"'), QString("\"\"")) % QChar('"'));
            out << "\n";
        }
    }
}
void SyncModelTest::readAddedSmsEventsFromConvModel()
{
    //Adding 2 sms events to  group
    qsrand(QDateTime::currentDateTime().toTime_t());
    QDateTime sentReceivedTime = QDateTime::fromTime_t(qrand());
    QVERIFY(addEvent(4098, group.id(), sentReceivedTime, "121", "122", "Added grouped msg 1 # 121-122", false));
    QVERIFY(addEvent(4098, group.id(), sentReceivedTime, "121", "122", "Added grouped msg 2 # 121-122", false));

    //getting the first event and comparing
    ConversationModel convModel;
    convModel.enableContactChanges(false);
    convModel.setQueryMode(EventModel::SyncQuery);
    QVERIFY(convModel.getEvents(group.id()));
    QVERIFY(convModel.rowCount() == 2);

    for (int i = 0; i < 2; i++) {
        Event e = convModel.event(convModel.index(i, 0));
        if (i == 0) {
            QVERIFY(e.freeText() == "Added grouped msg 2 # 121-122");
        } else if (i == 1) {
            QVERIFY(e.freeText() == "Added grouped msg 1 # 121-122");
        }
    }

}
void ConversationModelTest::sorting()
{
    EventModel model;
    model.setQueryMode(EventModel::StreamedAsyncQuery);
    model.setFirstChunkSize(5);
    model.enableContactChanges(false);
    watcher.setModel(&model);

    //add events with the same timestamp
    QDateTime now = QDateTime::currentDateTime();
    QDateTime future = now.addSecs(10);

    addTestEvent(model, Event::SMSEvent, Event::Inbound, ACCOUNT1,
                 group1.id(), "I", false, false, now);
    addTestEvent(model, Event::SMSEvent, Event::Inbound, ACCOUNT1,
                 group1.id(), "II", false, false, now);
    addTestEvent(model, Event::SMSEvent, Event::Inbound, ACCOUNT1,
                 group1.id(), "III", false, false, future);
    addTestEvent(model, Event::SMSEvent, Event::Inbound, ACCOUNT1,
                 group1.id(), "IV", false, false, future);
    addTestEvent(model, Event::SMSEvent, Event::Inbound, ACCOUNT1,
                 group1.id(), "V", false, false, future);

    watcher.waitForSignals(5, 5);

    ConversationModel conv;
    conv.setQueryMode(EventModel::StreamedAsyncQuery);
    conv.setFirstChunkSize(5);
    conv.enableContactChanges(false);
    QSignalSpy rowsInserted(&conv, SIGNAL(rowsInserted(const QModelIndex &, int, int)));

    QVERIFY(conv.getEvents(group1.id()));

    QVERIFY(waitSignal(rowsInserted));

    QVERIFY(conv.rowCount() >= 5 );

    QCOMPARE(conv.event(conv.index(0, 0)).freeText(), QLatin1String("V"));
    QCOMPARE(conv.event(conv.index(1, 0)).freeText(), QLatin1String("IV"));
    QCOMPARE(conv.event(conv.index(2, 0)).freeText(), QLatin1String("III"));
    QCOMPARE(conv.event(conv.index(3, 0)).freeText(), QLatin1String("II"));
    QCOMPARE(conv.event(conv.index(4, 0)).freeText(), QLatin1String("I"));
}
void ConversationModelTest::deleteEvent()
{
    ConversationModel model;
    model.enableContactChanges(false);
    watcher.setModel(&model);
    model.setQueryMode(EventModel::SyncQuery);
    QVERIFY(model.getEvents(group1.id()));

    Event event;
    /* delete invalid event */
    QVERIFY(!model.deleteEvent(event));

    int rows = model.rowCount();
    int row = rand() % rows;
    event = model.event(model.index(row, 0));
    qDebug() << row << event.id();
    QVERIFY(model.deleteEvent(event.id()));
    watcher.waitForSignals();
    QVERIFY(!model.trackerIO().getEvent(event.id(), event));
    QVERIFY(model.event(model.index(row, 0)).id() != event.id());
    QVERIFY(model.rowCount() == rows - 1);
}
int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    ConversationModel model;

    GroupModel groupModel;
    groupModel.setQueryMode(EventModel::SyncQuery);
    groupModel.getGroups("/org/freedesktop/Telepathy/Account/gabble/jabber/dut_40localhost0");

    model.getEvents(groupModel.group(groupModel.index(0, 0)).id());

    QTableView view;
    view.setModel(&model);
    view.show();

#if 0
    // Examples for accessing group data. You'll have to either use
    // SyncQuery mode or wait for rowsInserted() or modelReady() before
    // you can iterate over the model data.

    for (int i = 0; i < model.rowCount(); i++) {
        // Model style:
        qDebug() << model.index(i, EventModel::EventId).data().toString() <<
            model.index(i, EventModel::StartTime).data().toDateTime() <<
            model.index(i, EventModel::LocalUid).data().toString() <<
            model.index(i, EventModel::RemoteUid).data().toString() <<
            model.index(i, EventModel::FreeText).data().toString();

        // Event style:
        Event e = model.event(model.index(i, 0));
        // or
        // Event e = model.index(i, 0).data(Qt::UserRole).value<Event>();

        qDebug() << e.id() << e.startTime() << e.localUid() <<
            e.remoteUid() << e.freeText();

    }
#endif

    int ret = app.exec();

    return ret;
}
void ConversationModelTest::getEvents()
{
    QFETCH(bool, useThread);

    QThread modelThread;

    ConversationModel model;
    model.enableContactChanges(false);
    watcher.setModel(&model);

    if (useThread) {
        modelThread.start();
        model.setBackgroundThread(&modelThread);
    }

    QVERIFY(model.getEvents(group1.id()));
    QVERIFY(watcher.waitForModelReady());

    QCOMPARE(model.rowCount(), 10);
    for (int i = 0; i < model.rowCount(); i++) {
        Event e1, e2;
        QModelIndex ind = model.index(i, 0);
        e1 = model.event(ind);
        QVERIFY(model.trackerIO().getEvent(e1.id(), e2));
        QVERIFY(compareEvents(e1, e2));
        QVERIFY(model.event(ind).type() != Event::CallEvent);
    }

    // add but don't save status message and check content again
    addTestEvent(model, Event::StatusMessageEvent, Event::Outbound, ACCOUNT1,
                 group1.id(), "status message", false, false,
                 QDateTime::currentDateTime(), QString(), true);
    watcher.waitForSignals(-1, 1);
    QCOMPARE(model.rowCount(), 11);
    for (int i = 0; i < model.rowCount(); i++)
        QVERIFY(model.event(model.index(i, 0)).type() != Event::CallEvent);
    // NOTE: since setFilter re-fetches data from tracker, status message event is lost

    /* filtering by type */
    QVERIFY(model.setFilter(Event::IMEvent));
    QVERIFY(watcher.waitForModelReady());
    QCOMPARE(model.rowCount(), 6);
    for (int i = 0; i < model.rowCount(); i++)
        QCOMPARE(model.event(model.index(i, 0)).type(), Event::IMEvent);

    QVERIFY(model.setFilter(Event::SMSEvent));
    QVERIFY(watcher.waitForModelReady());
    QCOMPARE(model.rowCount(), 4);
    for (int i = 0; i < model.rowCount(); i++)
        QCOMPARE(model.event(model.index(i, 0)).type(), Event::SMSEvent);

    /* filtering by account */
    QVERIFY(model.setFilter(Event::UnknownType, ACCOUNT1));
    QVERIFY(watcher.waitForModelReady());
    QCOMPARE(model.rowCount(), 6);
    for (int i = 0; i < model.rowCount(); i++)
        QCOMPARE(model.event(model.index(i, 0)).localUid(), ACCOUNT1);

    QVERIFY(model.setFilter(Event::UnknownType, ACCOUNT2));
    QVERIFY(watcher.waitForModelReady());
    QCOMPARE(model.rowCount(), 4);
    for (int i = 0; i < model.rowCount(); i++)
        QCOMPARE(model.event(model.index(i, 0)).localUid(), ACCOUNT2);

    /* filtering by direction */
    QVERIFY(model.setFilter(Event::UnknownType, QString(), Event::Inbound));
    QVERIFY(watcher.waitForModelReady());
    QCOMPARE(model.rowCount(), 5);
    for (int i = 0; i < model.rowCount(); i++)
        QCOMPARE(model.event(model.index(i, 0)).direction(), Event::Inbound);

    QVERIFY(model.setFilter(Event::UnknownType, QString(), Event::Outbound));
    QVERIFY(watcher.waitForModelReady());
    QCOMPARE(model.rowCount(), 5);
    for (int i = 0; i < model.rowCount(); i++)
        QCOMPARE(model.event(model.index(i, 0)).direction(), Event::Outbound);

    /* mixed filtering */
    QVERIFY(model.setFilter(Event::IMEvent, ACCOUNT1, Event::Outbound));
    QVERIFY(watcher.waitForModelReady());
    QCOMPARE(model.rowCount(), 2);
    for (int i = 0; i < model.rowCount(); i++) {
        QCOMPARE(model.event(model.index(i, 0)).type(), Event::IMEvent);
        QCOMPARE(model.event(model.index(i, 0)).localUid(), ACCOUNT1);
        QCOMPARE(model.event(model.index(i, 0)).direction(), Event::Outbound);
    }

    modelThread.quit();
    modelThread.wait(3000);
}
void ConversationModelTest::addEvent()
{
    ConversationModel model;
    model.enableContactChanges(false);
    watcher.setModel(&model);
    model.setQueryMode(EventModel::SyncQuery);
    QVERIFY(model.getEvents(group1.id()));
    int rows = model.rowCount();

    QVERIFY(addTestEvent(model, Event::IMEvent, Event::Outbound, ACCOUNT1,
                         group1.id(), "added event") != -1);
    watcher.waitForSignals();
    rows++;
    QCOMPARE(model.rowCount(), rows);
    QCOMPARE(model.event(model.index(0, 0)).freeText(), QString("added event"));

    /* filtering by type */
    QVERIFY(model.setFilter(Event::IMEvent));
    rows = model.rowCount();
    QVERIFY(addTestEvent(model, Event::IMEvent, Event::Inbound, ACCOUNT1,
                         group1.id(), "im 1") != -1);
    watcher.waitForSignals();
    QVERIFY(addTestEvent(model, Event::SMSEvent, Event::Inbound, ACCOUNT1,
                         group1.id(), "sms 1") != -1);
    watcher.waitForSignals();
    QCOMPARE(model.rowCount(), rows + 1);
    QCOMPARE(model.event(model.index(0, 0)).freeText(), QString("im 1"));

    /* filtering by account */
    QVERIFY(model.setFilter(Event::UnknownType, ACCOUNT1));
    rows = model.rowCount();
    QVERIFY(addTestEvent(model, Event::SMSEvent, Event::Inbound, ACCOUNT2,
                         group1.id(), "account 2") != -1);
    watcher.waitForSignals();
    QVERIFY(addTestEvent(model, Event::SMSEvent, Event::Inbound, ACCOUNT1,
                         group1.id(), "account 1") != -1);
    watcher.waitForSignals();
    QVERIFY(addTestEvent(model, Event::IMEvent, Event::Outbound, ACCOUNT1,
                         group1.id(), "account 1") != -1);
    watcher.waitForSignals();
    QCOMPARE(model.rowCount(), rows + 2);
    QCOMPARE(model.event(model.index(0, 0)).freeText(), QString("account 1"));

    /* filtering by direction */
    QVERIFY(model.setFilter(Event::UnknownType, "", Event::Inbound));
    rows = model.rowCount();
    QVERIFY(addTestEvent(model, Event::SMSEvent, Event::Inbound, ACCOUNT2,
                         group1.id(), "in") != -1);
    watcher.waitForSignals();
    QVERIFY(addTestEvent(model, Event::SMSEvent, Event::Outbound, ACCOUNT1,
                         group1.id(), "out") != -1);
    watcher.waitForSignals();
    QVERIFY(addTestEvent(model, Event::IMEvent, Event::Inbound, ACCOUNT1,
                         group1.id(), "in") != -1);
    watcher.waitForSignals();
    QCOMPARE(model.rowCount(), rows + 2);
    QCOMPARE(model.event(model.index(0, 0)).freeText(), QString("in"));

    /* mixed filtering */
    QVERIFY(model.setFilter(Event::SMSEvent, ACCOUNT2, Event::Inbound));
    rows = model.rowCount();
    QVERIFY(addTestEvent(model, Event::IMEvent, Event::Inbound, ACCOUNT2,
                         group1.id(), "added event") != -1);
    watcher.waitForSignals();
    QCOMPARE(model.rowCount(), rows);
    QVERIFY(addTestEvent(model, Event::SMSEvent, Event::Inbound, ACCOUNT2,
                         group1.id(), "filtering works") != -1);
    watcher.waitForSignals();
    QCOMPARE(model.rowCount(), rows + 1);
    QCOMPARE(model.event(model.index(0, 0)).freeText(), QString("filtering works"));
}