summaryrefslogtreecommitdiffstats
path: root/tests/notificationtest.cpp
blob: 9433586139e97e03566824700c4f7f7ba65e6ad1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <QtTest>

#include <QString>
#include <QSignalSpy>

#include "store.h"
#include "resourceconfig.h"
#include "resourcecontrol.h"
#include "modelresult.h"
#include "log.h"
#include "test.h"
#include "testutils.h"
#include "notifier.h"
#include "notification.h"

using namespace Sink;
using namespace Sink::ApplicationDomain;

/**
 * Test of complete system using the dummy resource.
 *
 * This test requires the dummy resource installed.
 */
class NotificationTest : public QObject
{
    Q_OBJECT

private slots:
    void initTestCase()
    {
        Sink::Test::initTest();
        ResourceConfig::addResource("sink.dummy.instance1", "sink.dummy");
    }

    void cleanup()
    {
        VERIFYEXEC(Sink::Store::removeDataFromDisk(QByteArray("sink.dummy.instance1")));
    }

    void testSyncNotifications()
    {
        auto query = Query().resourceFilter("sink.dummy.instance1");
        query.setType<ApplicationDomain::Mail>();
        query.filter("id1");
        query.filter("id2");

        QList<Sink::Notification> statusNotifications;
        QList<Sink::Notification> infoNotifications;
        Sink::Notifier notifier("sink.dummy.instance1");
        notifier.registerHandler([&] (const Sink::Notification &n){
            SinkLogCtx(Sink::Log::Context{"dummyresourcetest"}) << "Received notification " << n;
            if (n.type == Notification::Status) {
                statusNotifications << n;
            }
            if (n.type == Notification::Info) {
                infoNotifications << n;
            }
        });

        // Ensure all local data is processed
        VERIFYEXEC(Sink::Store::synchronize(query));
        VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(QByteArrayList() << "sink.dummy.instance1"));

        //FIXME it can happen that we get a changereplay notification pair first.
        QTRY_COMPARE(statusNotifications.size(), 5);
        //Sync
        QCOMPARE(statusNotifications.at(0).code, static_cast<int>(ApplicationDomain::Status::ConnectedStatus));
        QCOMPARE(statusNotifications.at(1).code, static_cast<int>(Sink::ApplicationDomain::Status::BusyStatus));
        QCOMPARE(statusNotifications.at(2).code, static_cast<int>(Sink::ApplicationDomain::Status::ConnectedStatus));
        //Changereplay
        QCOMPARE(statusNotifications.at(3).code, static_cast<int>(Sink::ApplicationDomain::Status::BusyStatus));
        QCOMPARE(statusNotifications.at(4).code, static_cast<int>(Sink::ApplicationDomain::Status::ConnectedStatus));

        QTRY_COMPARE(infoNotifications.size(), 2);
        QCOMPARE(infoNotifications.at(0).code, static_cast<int>(ApplicationDomain::SyncStatus::SyncInProgress));
        QCOMPARE(infoNotifications.at(0).entities, QList<QByteArray>{} << "id1" << "id2");
        QCOMPARE(infoNotifications.at(1).code, static_cast<int>(ApplicationDomain::SyncStatus::SyncSuccess));
        QCOMPARE(infoNotifications.at(1).entities, QList<QByteArray>{} << "id1" << "id2");

        QCOMPARE(infoNotifications.at(1).code, static_cast<int>(ApplicationDomain::SyncStatus::SyncSuccess));
    }

    void testModelNotifications()
    {
        auto query = Query().resourceFilter("sink.dummy.instance1");
        query.setType<ApplicationDomain::Mail>();
        query.setFlags(Query::LiveQuery | Query::UpdateStatus);

        VERIFYEXEC(Sink::Store::synchronize(query));
        VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(QByteArrayList() << "sink.dummy.instance1"));

        auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Mail>(query);
        QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool());
        QVERIFY(model->rowCount() >= 1);

        QSignalSpy changedSpy(model.data(), &QAbstractItemModel::dataChanged);
        auto mail = model->index(0, 0, QModelIndex()).data(Sink::Store::DomainObjectRole).value<Mail::Ptr>();
        auto newQuery = query;
        newQuery.filter(mail->identifier());

        QList<int> status;
        QObject::connect(model.data(), &QAbstractItemModel::dataChanged, [&] (const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles) {
            QVERIFY(begin.row() == end.row());
            if (begin.row() == 0) {
                status << model->data(begin, Store::StatusRole).value<int>();
                // qWarning() << "New status: " << status.last() << roles;
            }
        });

        //This will trigger a modification of all previous items as well.
        VERIFYEXEC(Sink::Store::synchronize(newQuery));
        VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(QByteArrayList() << "sink.dummy.instance1"));

        QCOMPARE(status.size(), 3);
        //Sync progress of item
        QCOMPARE(status.at(0), static_cast<int>(ApplicationDomain::SyncStatus::SyncInProgress));
        QCOMPARE(status.at(1), static_cast<int>(ApplicationDomain::SyncStatus::SyncSuccess));
        //Modification triggered during sync
        QCOMPARE(status.at(2), static_cast<int>(ApplicationDomain::SyncStatus::SyncSuccess));
    }
};

QTEST_MAIN(NotificationTest)
#include "notificationtest.moc"