1 /*
2 SPDX-FileCopyrightText: 2010 Casey Link <unnamedrambler@gmail.com>
3 SPDX-FileCopyrightText: 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7
8 #include "conflictresolvertest.h"
9 #include "conflictresolver.h"
10
11 #include <KCalendarCore/Duration>
12 #include <KCalendarCore/Event>
13 #include <KCalendarCore/Period>
14
15 #include <QTest>
16 #include <QWidget>
17
18 using namespace IncidenceEditorNG;
19
insertAttendees()20 void ConflictResolverTest::insertAttendees()
21 {
22 for (const CalendarSupport::FreeBusyItem::Ptr &item : std::as_const(attendees)) {
23 resolver->insertAttendee(item);
24 }
25 }
26
addAttendee(const QString & email,const KCalendarCore::FreeBusy::Ptr & fb,KCalendarCore::Attendee::Role role)27 void ConflictResolverTest::addAttendee(const QString &email, const KCalendarCore::FreeBusy::Ptr &fb, KCalendarCore::Attendee::Role role)
28 {
29 QString name = QStringLiteral("attendee %1").arg(attendees.count());
30 CalendarSupport::FreeBusyItem::Ptr item(
31 new CalendarSupport::FreeBusyItem(KCalendarCore::Attendee(name, email, false, KCalendarCore::Attendee::Accepted, role), nullptr));
32 item->setFreeBusy(KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(*fb.data())));
33 attendees << item;
34 }
35
initTestCase()36 void ConflictResolverTest::initTestCase()
37 {
38 parent = new QWidget;
39 init();
40 }
41
init()42 void ConflictResolverTest::init()
43 {
44 base = QDateTime::currentDateTime().addDays(1);
45 end = base.addSecs(10 * 60 * 60);
46 resolver = new ConflictResolver(parent, parent);
47 }
48
cleanup()49 void ConflictResolverTest::cleanup()
50 {
51 delete resolver;
52 resolver = nullptr;
53 attendees.clear();
54 }
55
simpleTest()56 void ConflictResolverTest::simpleTest()
57 {
58 KCalendarCore::Period meeting(end.addSecs(-3 * 60 * 60), KCalendarCore::Duration(2 * 60 * 60));
59 addAttendee(QStringLiteral("albert@einstein.net"), KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List() << meeting)));
60
61 insertAttendees();
62
63 static const int resolution = 15 * 60;
64 resolver->setResolution(resolution);
65 resolver->setEarliestDateTime(base);
66 resolver->setLatestDateTime(end);
67 resolver->findAllFreeSlots();
68
69 QVERIFY(resolver->availableSlots().size() == 2);
70
71 KCalendarCore::Period first = resolver->availableSlots().at(0);
72 QCOMPARE(first.start(), base);
73 QCOMPARE(first.end(), meeting.start());
74
75 KCalendarCore::Period second = resolver->availableSlots().at(1);
76 QEXPECT_FAIL("", "Got broken in revision f17b9a8c975588ad7cf4ce8b94ab8e32ac193ed8", Continue);
77 QCOMPARE(second.start(), meeting.end().addSecs(resolution)); // add 15 minutes because the
78 // free block doesn't start until
79 // the next timeslot
80 QCOMPARE(second.end(), end);
81 }
82
stillPrettySimpleTest()83 void ConflictResolverTest::stillPrettySimpleTest()
84 {
85 KCalendarCore::Period meeting1(base, KCalendarCore::Duration(2 * 60 * 60));
86 KCalendarCore::Period meeting2(base.addSecs(60 * 60), KCalendarCore::Duration(2 * 60 * 60));
87 KCalendarCore::Period meeting3(end.addSecs(-3 * 60 * 60), KCalendarCore::Duration(2 * 60 * 60));
88 addAttendee(QStringLiteral("john.f@kennedy.com"),
89 KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List() << meeting1 << meeting3)));
90 addAttendee(QStringLiteral("elvis@rock.com"),
91 KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List() << meeting2 << meeting3)));
92 addAttendee(QStringLiteral("albert@einstein.net"), KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List() << meeting3)));
93
94 insertAttendees();
95
96 static const int resolution = 15 * 60;
97 resolver->setResolution(resolution);
98 resolver->setEarliestDateTime(base);
99 resolver->setLatestDateTime(end);
100 resolver->findAllFreeSlots();
101
102 QVERIFY(resolver->availableSlots().size() == 2);
103
104 KCalendarCore::Period first = resolver->availableSlots().at(0);
105 QEXPECT_FAIL("", "Got broken in revision f17b9a8c975588ad7cf4ce8b94ab8e32ac193ed8", Continue);
106 QCOMPARE(first.start(), meeting2.end().addSecs(resolution));
107 QCOMPARE(first.end(), meeting3.start());
108
109 KCalendarCore::Period second = resolver->availableSlots().at(1);
110 QEXPECT_FAIL("", "Got broken in revision f17b9a8c975588ad7cf4ce8b94ab8e32ac193ed8", Continue);
111 QCOMPARE(second.start(), meeting3.end().addSecs(resolution)); // add 15 minutes because the
112 // free block doesn't start until
113 // the next timeslot
114 QCOMPARE(second.end(), end);
115 }
116
117 #define _time(h, m) QDateTime(base.date(), QTime(h, m))
118
akademy2010()119 void ConflictResolverTest::akademy2010()
120 {
121 // based off akademy 2010 schedule
122
123 // first event was at 9:30, so lets align our start time there
124 base.setTime(QTime(9, 30));
125 end = base.addSecs(8 * 60 * 60);
126 KCalendarCore::Period opening(_time(9, 30), _time(9, 45));
127 KCalendarCore::Period keynote(_time(9, 45), _time(10, 30));
128
129 KCalendarCore::Period sevenPrinciples(_time(10, 30), _time(11, 15));
130 KCalendarCore::Period commAsService(_time(10, 30), _time(11, 15));
131
132 KCalendarCore::Period kdeForums(_time(11, 15), _time(11, 45));
133 KCalendarCore::Period oviStore(_time(11, 15), _time(11, 45));
134
135 // 10 min break
136
137 KCalendarCore::Period highlights(_time(12, 0), _time(12, 45));
138 KCalendarCore::Period styles(_time(12, 0), _time(12, 45));
139
140 KCalendarCore::Period wikimedia(_time(12, 45), _time(13, 15));
141 KCalendarCore::Period avalanche(_time(12, 45), _time(13, 15));
142
143 KCalendarCore::Period pimp(_time(13, 15), _time(13, 45));
144 KCalendarCore::Period direction(_time(13, 15), _time(13, 45));
145
146 // lunch 1 hr 25 min lunch
147
148 KCalendarCore::Period blurr(_time(15, 15), _time(16, 00));
149 KCalendarCore::Period plasma(_time(15, 15), _time(16, 00));
150
151 // for ( int i = 1; i < 80; ++i ) {
152 // adds 80 people (adds the same 8 people 10 times)
153 addAttendee(
154 QStringLiteral("akademyattendee1@email.com"),
155 KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List() << opening << keynote << oviStore << wikimedia << direction)));
156 addAttendee(
157 QStringLiteral("akademyattendee2@email.com"),
158 KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List() << opening << keynote << commAsService << highlights << pimp)));
159 addAttendee(QStringLiteral("akademyattendee3@email.com"),
160 KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List() << opening << kdeForums << styles << pimp << plasma)));
161 addAttendee(QStringLiteral("akademyattendee4@email.com"),
162 KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List() << opening << keynote << oviStore << pimp << blurr)));
163 addAttendee(QStringLiteral("akademyattendee5@email.com"),
164 KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List() << keynote << oviStore << highlights << avalanche)));
165 addAttendee(QStringLiteral("akademyattendee6@email.com"),
166 KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List() << opening << keynote << commAsService << highlights)));
167 addAttendee(QStringLiteral("akademyattendee7@email.com"),
168 KCalendarCore::FreeBusy::Ptr(
169 new KCalendarCore::FreeBusy(KCalendarCore::Period::List() << opening << kdeForums << styles << avalanche << pimp << plasma)));
170 addAttendee(
171 QStringLiteral("akademyattendee8@email.com"),
172 KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List() << opening << keynote << oviStore << wikimedia << blurr)));
173 // }
174
175 insertAttendees();
176
177 const int resolution = 5 * 60;
178 resolver->setResolution(resolution);
179 resolver->setEarliestDateTime(base);
180 resolver->setLatestDateTime(end);
181 // QBENCHMARK {
182 resolver->findAllFreeSlots();
183 // }
184
185 QVERIFY(resolver->availableSlots().size() == 3);
186 QEXPECT_FAIL("", "Got broken in revision f17b9a8c975588ad7cf4ce8b94ab8e32ac193ed8", Abort);
187 QCOMPARE(resolver->availableSlots().at(0).duration(), KCalendarCore::Duration(10 * 60));
188 QCOMPARE(resolver->availableSlots().at(1).duration(), KCalendarCore::Duration(1 * 60 * 60 + 25 * 60));
189 QVERIFY(resolver->availableSlots().at(2).start() > plasma.end());
190 }
191
testPeriodIsLargerThenTimeframe()192 void ConflictResolverTest::testPeriodIsLargerThenTimeframe()
193 {
194 base.setDate(QDate(2010, 7, 29));
195 base.setTime(QTime(7, 30));
196
197 end.setDate(QDate(2010, 7, 29));
198 end.setTime(QTime(8, 30));
199
200 KCalendarCore::Period testEvent(_time(5, 45), _time(8, 45));
201
202 addAttendee(QStringLiteral("kdabtest1@demo.kolab.org"),
203 KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List() << testEvent)));
204 addAttendee(QStringLiteral("kdabtest2@demo.kolab.org"), KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List())));
205
206 insertAttendees();
207 resolver->setEarliestDateTime(base);
208 resolver->setLatestDateTime(end);
209 resolver->findAllFreeSlots();
210
211 QCOMPARE(resolver->availableSlots().size(), 0);
212 }
213
testPeriodBeginsBeforeTimeframeBegins()214 void ConflictResolverTest::testPeriodBeginsBeforeTimeframeBegins()
215 {
216 base.setDate(QDate(2010, 7, 29));
217 base.setTime(QTime(7, 30));
218
219 end.setDate(QDate(2010, 7, 29));
220 end.setTime(QTime(9, 30));
221
222 KCalendarCore::Period testEvent(_time(5, 45), _time(8, 45));
223
224 addAttendee(QStringLiteral("kdabtest1@demo.kolab.org"),
225 KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List() << testEvent)));
226 addAttendee(QStringLiteral("kdabtest2@demo.kolab.org"), KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List())));
227
228 insertAttendees();
229 resolver->setEarliestDateTime(base);
230 resolver->setLatestDateTime(end);
231 resolver->findAllFreeSlots();
232
233 QCOMPARE(resolver->availableSlots().size(), 1);
234 KCalendarCore::Period freeslot = resolver->availableSlots().at(0);
235 QCOMPARE(freeslot.start(), _time(8, 45));
236 QCOMPARE(freeslot.end(), end);
237 }
238
testPeriodEndsAfterTimeframeEnds()239 void ConflictResolverTest::testPeriodEndsAfterTimeframeEnds()
240 {
241 base.setDate(QDate(2010, 7, 29));
242 base.setTime(QTime(7, 30));
243
244 end.setDate(QDate(2010, 7, 29));
245 end.setTime(QTime(9, 30));
246
247 KCalendarCore::Period testEvent(_time(8, 00), _time(9, 45));
248
249 addAttendee(QStringLiteral("kdabtest1@demo.kolab.org"),
250 KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List() << testEvent)));
251 addAttendee(QStringLiteral("kdabtest2@demo.kolab.org"), KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List())));
252
253 insertAttendees();
254 resolver->setEarliestDateTime(base);
255 resolver->setLatestDateTime(end);
256 resolver->findAllFreeSlots();
257
258 QCOMPARE(resolver->availableSlots().size(), 1);
259 KCalendarCore::Period freeslot = resolver->availableSlots().at(0);
260 QCOMPARE(freeslot.duration(), KCalendarCore::Duration(30 * 60));
261 QCOMPARE(freeslot.start(), base);
262 QCOMPARE(freeslot.end(), _time(8, 00));
263 }
264
testPeriodEndsAtSametimeAsTimeframe()265 void ConflictResolverTest::testPeriodEndsAtSametimeAsTimeframe()
266 {
267 base.setDate(QDate(2010, 7, 29));
268 base.setTime(QTime(7, 45));
269
270 end.setDate(QDate(2010, 7, 29));
271 end.setTime(QTime(8, 45));
272
273 KCalendarCore::Period testEvent(_time(5, 45), _time(8, 45));
274
275 addAttendee(QStringLiteral("kdabtest1@demo.kolab.org"),
276 KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List() << testEvent)));
277 addAttendee(QStringLiteral("kdabtest2@demo.kolab.org"), KCalendarCore::FreeBusy::Ptr(new KCalendarCore::FreeBusy(KCalendarCore::Period::List())));
278
279 insertAttendees();
280 resolver->setEarliestDateTime(base);
281 resolver->setLatestDateTime(end);
282 resolver->findAllFreeSlots();
283
284 QCOMPARE(resolver->availableSlots().size(), 0);
285 }
286
287 QTEST_MAIN(ConflictResolverTest)
288