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"
|