Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F16571010
akappendhandlertest.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
32 KB
Referenced Files
None
Subscribers
None
akappendhandlertest.cpp
View Options
/*
Copyright (c) 2014 Daniel Vrátil <dvratil@redhat.com>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include
<QObject>
#include
<QSettings>
#include
<handler/akappend.h>
#include
<imapstreamparser.h>
#include
<response.h>
#include
<storage/selectquerybuilder.h>
#include
<private/notificationmessagev3_p.h>
#include
<private/notificationmessagev2_p.h>
#include
<private/imapparser_p.h>
#include
"fakeakonadiserver.h"
#include
"fakeentities.h"
#include
<shared/aktest.h>
#include
<shared/akstandarddirs.h>
#include
<QtTest/QTest>
#include
<QSignalSpy>
using
namespace
Akonadi
;
using
namespace
Akonadi
::
Server
;
Q_DECLARE_METATYPE
(
PimItem
)
Q_DECLARE_METATYPE
(
QVector
<
Flag
>
)
Q_DECLARE_METATYPE
(
QVector
<
FakePart
>
)
Q_DECLARE_METATYPE
(
QVector
<
FakeTag
>
)
class
AkAppendHandlerTest
:
public
QObject
{
Q_OBJECT
public
:
AkAppendHandlerTest
()
{
qRegisterMetaType
<
Akonadi
::
Server
::
Response
>
();
// Effectively disable external payload parts, we have a dedicated unit-test
// for that
const
QString
serverConfigFile
=
AkStandardDirs
::
serverConfigFile
(
XdgBaseDirs
::
ReadWrite
);
QSettings
settings
(
serverConfigFile
,
QSettings
::
IniFormat
);
settings
.
setValue
(
QLatin1String
(
"General/SizeThreshold"
),
std
::
numeric_limits
<
qint64
>::
max
());
try
{
FakeAkonadiServer
::
instance
()
->
init
();
}
catch
(
const
FakeAkonadiServerException
&
e
)
{
akError
()
<<
e
.
what
();
akFatal
()
<<
"Fake Akonadi Server failed to start up, aborting test"
;
}
}
~
AkAppendHandlerTest
()
{
FakeAkonadiServer
::
instance
()
->
quit
();
}
void
updatePimItem
(
PimItem
&
pimItem
,
const
QString
&
remoteId
,
const
qint64
size
)
{
pimItem
.
setRemoteId
(
remoteId
);
pimItem
.
setGid
(
remoteId
);
pimItem
.
setSize
(
size
);
}
void
updateNotifcationEntity
(
NotificationMessageV3
&
ntf
,
const
PimItem
&
pimItem
)
{
ntf
.
clearEntities
();
ntf
.
addEntity
(
pimItem
.
id
(),
pimItem
.
remoteId
(),
pimItem
.
remoteRevision
(),
pimItem
.
mimeType
().
name
());
}
struct
PartHelper
{
PartHelper
(
const
QString
&
type_
,
const
QByteArray
&
data_
,
int
size_
,
bool
external_
=
false
,
int
version_
=
0
)
:
type
(
type_
)
,
data
(
data_
)
,
size
(
size_
)
,
external
(
external_
)
,
version
(
version_
)
{
}
QString
type
;
QByteArray
data
;
int
size
;
bool
external
;
int
version
;
};
void
updateParts
(
QVector
<
FakePart
>
&
parts
,
const
std
::
vector
<
PartHelper
>
&
updatedParts
)
{
parts
.
clear
();
Q_FOREACH
(
const
PartHelper
&
helper
,
updatedParts
)
{
FakePart
part
;
const
QStringList
types
=
helper
.
type
.
split
(
QLatin1Char
(
':'
));
Q_ASSERT
(
types
.
count
()
==
2
);
part
.
setPartType
(
PartType
(
types
[
1
],
types
[
0
]));
part
.
setData
(
helper
.
data
);
part
.
setDatasize
(
helper
.
size
);
part
.
setExternal
(
helper
.
external
);
part
.
setVersion
(
helper
.
version
);
parts
<<
part
;
}
}
void
updateFlags
(
QVector
<
Flag
>
&
flags
,
const
QStringList
&
updatedFlags
)
{
flags
.
clear
();
Q_FOREACH
(
const
QString
&
flagName
,
updatedFlags
)
{
Flag
flag
;
flag
.
setName
(
flagName
);
flags
<<
flag
;
}
}
struct
TagHelper
{
TagHelper
(
const
QString
&
tagType_
,
const
QString
&
gid_
,
const
QString
&
remoteId_
=
QString
())
:
tagType
(
tagType_
)
,
gid
(
gid_
)
,
remoteId
(
remoteId_
)
{
}
QString
tagType
;
QString
gid
;
QString
remoteId
;
};
void
updateTags
(
QVector
<
FakeTag
>
&
tags
,
const
std
::
vector
<
TagHelper
>
&
updatedTags
)
{
tags
.
clear
();
Q_FOREACH
(
const
TagHelper
&
helper
,
updatedTags
)
{
FakeTag
tag
;
TagType
tagType
;
tagType
.
setName
(
helper
.
tagType
);
tag
.
setTagType
(
tagType
);
tag
.
setGid
(
helper
.
gid
);
tag
.
setRemoteId
(
helper
.
remoteId
);
tags
<<
tag
;
}
}
QByteArray
createCommand
(
const
PimItem
&
pimItem
,
const
QDateTime
&
dt
,
qint64
overrideSize
=
-1
)
{
const
qint64
size
=
overrideSize
>
-1
?
overrideSize
:
pimItem
.
size
();
return
"C: 2 X-AKAPPEND "
+
QByteArray
::
number
(
pimItem
.
collectionId
())
+
" "
+
QByteArray
::
number
(
size
)
+
" "
+
"(
\\
RemoteId["
+
pimItem
.
remoteId
().
toLatin1
()
+
"] "
+
"
\\
MimeType["
+
pimItem
.
mimeType
().
name
().
toLatin1
()
+
"] "
+
"
\\
RemoteRevision["
+
pimItem
.
remoteRevision
().
toLatin1
()
+
"] "
+
"
\\
Gid["
+
pimItem
.
gid
().
toLatin1
()
+
"]) "
+
"
\"
"
+
dt
.
toString
(
QLatin1String
(
"dd-MMM-yyyy hh:mm:ss"
)).
toLatin1
()
+
" +0000
\"
"
;
}
private
Q_SLOTS
:
void
testAkAppend_data
()
{
QTest
::
addColumn
<
QList
<
QByteArray
>
>
(
"scenario"
);
QTest
::
addColumn
<
NotificationMessageV3
>
(
"notification"
);
QTest
::
addColumn
<
PimItem
>
(
"pimItem"
);
QTest
::
addColumn
<
QVector
<
FakePart
>
>
(
"parts"
);
QTest
::
addColumn
<
QVector
<
Flag
>
>
(
"flags"
);
QTest
::
addColumn
<
QVector
<
FakeTag
>
>
(
"tags"
);
QTest
::
addColumn
<
qint64
>
(
"uidnext"
);
QTest
::
addColumn
<
QDateTime
>
(
"datetime"
);
QTest
::
addColumn
<
bool
>
(
"expectFail"
);
QList
<
QByteArray
>
scenario
;
NotificationMessageV3
notification
;
qint64
uidnext
=
0
;
QDateTime
datetime
(
QDate
(
2014
,
05
,
12
),
QTime
(
14
,
46
,
00
));
PimItem
pimItem
;
QVector
<
FakePart
>
parts
;
QVector
<
Flag
>
flags
;
QVector
<
FakeTag
>
tags
;
pimItem
.
setCollectionId
(
4
);
pimItem
.
setSize
(
10
);
pimItem
.
setRemoteId
(
QLatin1String
(
"TEST-1"
));
pimItem
.
setRemoteRevision
(
QLatin1String
(
"1"
));
pimItem
.
setGid
(
QLatin1String
(
"TEST-1"
));
pimItem
.
setMimeType
(
MimeType
::
retrieveByName
(
QLatin1String
(
"application/octet-stream"
)));
pimItem
.
setDatetime
(
datetime
);
updateParts
(
parts
,
{
{
QLatin1String
(
"PLD:DATA"
),
"0123456789"
,
10
}
});
notification
.
setType
(
NotificationMessageV2
::
Items
);
notification
.
setOperation
(
NotificationMessageV2
::
Add
);
notification
.
setParentCollection
(
4
);
notification
.
setResource
(
"akonadi_fake_resource_0"
);
notification
.
addEntity
(
-1
,
QLatin1String
(
"TEST-1"
),
QLatin1String
(
"1"
),
QLatin1String
(
"application/octet-stream"
));
notification
.
setSessionId
(
FakeAkonadiServer
::
instanceName
().
toLatin1
());
uidnext
=
13
;
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
createCommand
(
pimItem
,
datetime
)
+
" (PLD:DATA[0] {10}"
<<
"S: + Ready for literal data (expecting 10 bytes)"
<<
"C: 0123456789)"
<<
"S: 2 [UIDNEXT 13 DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 2 OK Append completed"
;
QTest
::
newRow
(
"single-part"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-2"
),
20
);
updateParts
(
parts
,
{
{
QLatin1String
(
"PLD:DATA"
),
"Random Data"
,
11
},
{
QLatin1String
(
"PLD:PLDTEST"
),
"Test Data"
,
9
}
});
updateNotifcationEntity
(
notification
,
pimItem
);
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
createCommand
(
pimItem
,
datetime
)
+
" (PLD:DATA[0] {11}"
<<
"S: + Ready for literal data (expecting 11 bytes)"
<<
"C: Random Data PLD:PLDTEST {9}"
<<
"S: + Ready for literal data (expecting 9 bytes)"
<<
"C: Test Data)"
<<
"S: 2 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 2 OK Append completed"
;
QTest
::
newRow
(
"multi-part"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
"C: 2 X-AKAPPEND 100 0 () ()"
<<
"S: 2 NO Unknown collection for '100'."
;
QTest
::
newRow
(
"invalid collection"
)
<<
scenario
<<
NotificationMessageV3
()
<<
PimItem
()
<<
QVector
<
FakePart
>
()
<<
QVector
<
Flag
>
()
<<
QVector
<
FakeTag
>
()
<<
-1ll
<<
QDateTime
()
<<
true
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
"C: 2 X-AKAPPEND 6 0 () ()"
<<
"S: 2 NO Cannot append item into virtual collection"
;
QTest
::
newRow
(
"virtual collection"
)
<<
scenario
<<
NotificationMessageV3
()
<<
PimItem
()
<<
QVector
<
FakePart
>
()
<<
QVector
<
Flag
>
()
<<
QVector
<
FakeTag
>
()
<<
-1ll
<<
QDateTime
()
<<
true
;
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-3"
),
5
);
updateParts
(
parts
,
{
{
QLatin1String
(
"PLD:DATA"
),
"12345"
,
5
}
});
updateNotifcationEntity
(
notification
,
pimItem
);
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
createCommand
(
pimItem
,
datetime
,
1
)
+
" (PLD:DATA[0] {5}"
<<
"S: + Ready for literal data (expecting 5 bytes)"
<<
"C: 12345)"
<<
"S: 2 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 2 OK Append completed"
;
QTest
::
newRow
(
"mismatch item sizes (smaller)"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-4"
),
1000
);
updateNotifcationEntity
(
notification
,
pimItem
);
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
createCommand
(
pimItem
,
datetime
)
+
" (PLD:DATA[0] {5}"
<<
"S: + Ready for literal data (expecting 5 bytes)"
<<
"C: 12345)"
<<
"S: 2 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 2 OK Append completed"
;
QTest
::
newRow
(
"mismatch item sizes (bigger)"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
createCommand
(
pimItem
,
datetime
)
+
" (PLD:DATA[0] {4}"
<<
"S: + Ready for literal data (expecting 4 bytes)"
<<
"C: 123"
<<
"S: 2 NO ImapParserException: Unable to read more data"
;
QTest
::
newRow
(
"incomplete part data"
)
<<
scenario
<<
NotificationMessageV3
()
<<
PimItem
()
<<
QVector
<
FakePart
>
()
<<
QVector
<
Flag
>
()
<<
QVector
<
FakeTag
>
()
<<
-1ll
<<
QDateTime
()
<<
true
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
createCommand
(
pimItem
,
datetime
)
+
" (PLD:DATA[0] {4}"
<<
"S: + Ready for literal data (expecting 4 bytes)"
<<
"C: 12345678910"
<<
"S: 2 NO PartTypeException: Invalid part type name."
;
QTest
::
newRow
(
"part data larger than advertised"
)
<<
scenario
<<
NotificationMessageV3
()
<<
PimItem
()
<<
QVector
<
FakePart
>
()
<<
QVector
<
Flag
>
()
<<
QVector
<
FakeTag
>
()
<<
-1ll
<<
QDateTime
()
<<
true
;
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-5"
),
0
);
updateParts
(
parts
,
{
{
QLatin1String
(
"PLD:DATA"
),
QByteArray
(),
0
}
});
updateNotifcationEntity
(
notification
,
pimItem
);
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
createCommand
(
pimItem
,
datetime
)
+
" (PLD:DATA[0] NIL)"
<<
"S: 2 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 2 OK Append completed"
;
QTest
::
newRow
(
"empty payload part"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-7"
),
0
);
updateNotifcationEntity
(
notification
,
pimItem
);
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
createCommand
(
pimItem
,
datetime
)
+
" (PLD:DATA[0] {0}"
<<
"S: + Ready for literal data (expecting 0 bytes)"
<<
"C: )"
<<
"S: 2 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 2 OK Append completed"
;
QTest
::
newRow
(
"empty part data"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-8"
),
1
);
updateParts
(
parts
,
{
{
QLatin1String
(
"PLD:DATA"
),
QByteArray
(
"
\0
"
,
1
),
1
}
});
updateNotifcationEntity
(
notification
,
pimItem
);
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
createCommand
(
pimItem
,
datetime
)
+
" (PLD:DATA[0] {1}"
<<
"S: + Ready for literal data (expecting 1 bytes)"
<<
"C: "
+
QByteArray
(
"
\0
"
,
1
)
+
")"
// otherwise QByteArray trims the string before"\0"
<<
"S: 2 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 2 OK Append completed"
;
QTest
::
newRow
(
"part data will null character"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
const
QString
utf8String
=
QString
::
fromUtf8
(
"äöüß@€µøđ¢©®"
);
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-9"
),
utf8String
.
toUtf8
().
size
());
updateParts
(
parts
,
{
{
QLatin1String
(
"PLD:DATA"
),
utf8String
.
toUtf8
(),
utf8String
.
toUtf8
().
size
()
}
});
updateNotifcationEntity
(
notification
,
pimItem
);
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
createCommand
(
pimItem
,
datetime
)
+
" (PLD:DATA[0] {"
+
QByteArray
::
number
(
parts
.
first
().
datasize
())
+
"}"
<<
"S: + Ready for literal data (expecting "
+
QByteArray
::
number
(
parts
.
first
().
datasize
())
+
" bytes)"
<<
"C: "
+
utf8String
.
toUtf8
()
+
")"
<<
"S: 2 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 2 OK Append completed"
;
QTest
::
newRow
(
"utf8 part data"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
const
QByteArray
hugeData
=
QByteArray
(
"a"
).
repeated
(
1
<<
20
);
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-10"
),
1
<<
20
);
updateParts
(
parts
,
{
{
QLatin1String
(
"PLD:DATA"
),
hugeData
,
1
<<
20
}
});
updateNotifcationEntity
(
notification
,
pimItem
);
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
createCommand
(
pimItem
,
datetime
)
+
" (PLD:DATA[0] {"
+
QByteArray
::
number
(
parts
.
first
().
datasize
())
+
"}"
<<
"S: + Ready for literal data (expecting "
+
QByteArray
::
number
(
parts
.
first
().
datasize
())
+
" bytes)"
<<
"C: "
+
hugeData
+
")"
<<
"S: 2 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 2 OK Append completed"
;
QTest
::
newRow
(
"huge part data"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
const
QByteArray
dataWithNewLines
=
"Bernard, Bernard, Bernard, Bernard, look, look Bernard!
\n
WHAT!!!!!!!
\n
I'm a prostitute robot from the future!"
;
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-11"
),
dataWithNewLines
.
size
());
updateParts
(
parts
,
{
{
QLatin1String
(
"PLD:DATA"
),
dataWithNewLines
,
dataWithNewLines
.
size
()
}
});
updateNotifcationEntity
(
notification
,
pimItem
);
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
createCommand
(
pimItem
,
datetime
)
+
" (PLD:DATA[0] {"
+
QByteArray
::
number
(
parts
.
first
().
datasize
())
+
"}"
<<
"S: + Ready for literal data (expecting "
+
QByteArray
::
number
(
parts
.
first
().
datasize
())
+
" bytes)"
<<
"C: "
+
dataWithNewLines
+
")"
<<
"S: 2 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 2 OK Append completed"
;
QTest
::
newRow
(
"data with newlines"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
const
QByteArray
lotsOfNewlines
=
QByteArray
(
"
\n
"
).
repeated
(
1
<<
20
);
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-12"
),
lotsOfNewlines
.
size
());
updateParts
(
parts
,
{
{
QLatin1String
(
"PLD:DATA"
),
lotsOfNewlines
,
lotsOfNewlines
.
size
()
}
});
updateNotifcationEntity
(
notification
,
pimItem
);
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
createCommand
(
pimItem
,
datetime
)
+
"(PLD:DATA[0] {"
+
QByteArray
::
number
(
parts
.
first
().
datasize
())
+
"}"
<<
"S: + Ready for literal data (expecting "
+
QByteArray
::
number
(
parts
.
first
().
datasize
())
+
" bytes)"
<<
"C: "
+
lotsOfNewlines
+
")"
<<
"S: 2 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 2 OK Append completed"
;
QTest
::
newRow
(
"data with lots of newlines"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-13"
),
20
);
updateParts
(
parts
,
{
{
QLatin1String
(
"PLD:NEWPARTTYPE1"
),
"0123456789"
,
10
},
{
QLatin1String
(
"PLD:NEWPARTTYPE2"
),
"9876543210"
,
10
}
});
updateNotifcationEntity
(
notification
,
pimItem
);
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
createCommand
(
pimItem
,
datetime
)
+
"(PLD:NEWPARTTYPE1[0] {10}"
<<
"S: + Ready for literal data (expecting 10 bytes)"
<<
"C: 0123456789 PLD:NEWPARTTYPE2[0] {10}"
<<
"S: + Ready for literal data (expecting 10 bytes)"
<<
"C: 9876543210)"
<<
"S: 2 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 2 OK Append completed"
;
QTest
::
newRow
(
"non-existent part types"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-14"
),
0
);
updateParts
(
parts
,
{});
updateFlags
(
flags
,
QStringList
()
<<
QLatin1String
(
"
\\
SEEN"
)
<<
QLatin1String
(
"
\\
RANDOM"
));
updateNotifcationEntity
(
notification
,
pimItem
);
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
"C: 2 X-AKAPPEND 4 0 (
\\
RemoteId[TEST-14]
\\
MimeType[application/octet-stream]
\\
RemoteRevision[1]
\\
Gid[TEST-14]
\\
SEEN
\\
RANDOM)
\"
12-May-2014 14:46:00 +0000
\"
()"
<<
"S: 2 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 2 OK Append completed"
;
QTest
::
newRow
(
"item with flags"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-15"
),
0
);
updateFlags
(
flags
,
{});
updateTags
(
tags
,
{
{
QLatin1String
(
"PLAIN"
),
QLatin1String
(
"TAG-1"
)
},
{
QLatin1String
(
"PLAIN"
),
QLatin1String
(
"TAG-2"
)
}
});
updateNotifcationEntity
(
notification
,
pimItem
);
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
"C: 2 X-AKAPPEND 4 0 (
\\
RemoteId[TEST-15]
\\
MimeType[application/octet-stream]
\\
RemoteRevision[1]
\\
Gid[TEST-15]
\\
Tag[TAG-1]
\\
Tag[TAG-2])
\"
12-May-2014 14:46:00 +0000
\"
()"
<<
"S: 2 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 2 OK Append completed"
;
QTest
::
newRow
(
"item with non-existent tags (GID)"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-16"
),
0
);
updateTags
(
tags
,
{
{
QLatin1String
(
"PLAIN"
),
QLatin1String
(
"TAG-3"
)
},
{
QLatin1String
(
"PLAIN"
),
QLatin1String
(
"TAG-4"
)
}
});
updateNotifcationEntity
(
notification
,
pimItem
);
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
FakeAkonadiServer
::
selectResourceScenario
(
QLatin1String
(
"akonadi_fake_resource_0"
))
<<
"C: 3 X-AKAPPEND 4 0 (
\\
RemoteId[TEST-16]
\\
MimeType[application/octet-stream]
\\
RemoteRevision[1]
\\
Gid[TEST-16]
\\
RTag[TAG-3]
\\
RTag[TAG-4])
\"
12-May-2014 14:46:00 +0000
\"
()"
<<
"S: 3 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 3 OK Append completed"
;
QTest
::
newRow
(
"item with non-existent tags (RID)"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-17"
),
0
);
updateNotifcationEntity
(
notification
,
pimItem
);
updateTags
(
tags
,
{
{
QLatin1String
(
"PLAIN"
),
QLatin1String
(
"TAG-1"
)
},
{
QLatin1String
(
"PLAIN"
),
QLatin1String
(
"TAG-2"
)
}
});
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
FakeAkonadiServer
::
selectResourceScenario
(
QLatin1String
(
"akonadi_fake_resource_0"
))
<<
"C: 3 X-AKAPPEND 4 0 (
\\
RemoteId[TEST-17]
\\
MimeType[application/octet-stream]
\\
RemoteRevision[1]
\\
Gid[TEST-17]
\\
RTag[TAG-1]
\\
RTag[TAG-2])
\"
12-May-2014 14:46:00 +0000
\"
()"
<<
"S: 3 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 3 OK Append completed"
;
QTest
::
newRow
(
"item with existing tags (RID)"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-18"
),
0
);
updateNotifcationEntity
(
notification
,
pimItem
);
updateTags
(
tags
,
{
{
QLatin1String
(
"PLAIN"
),
QLatin1String
(
"TAG-3"
)
},
{
QLatin1String
(
"PLAIN"
),
QLatin1String
(
"TAG-4"
)
}
});
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
"C: 2 X-AKAPPEND 4 0 (
\\
RemoteId[TEST-18]
\\
MimeType[application/octet-stream]
\\
RemoteRevision[1]
\\
Gid[TEST-18]
\\
Tag[TAG-3]
\\
Tag[TAG-4])
\"
12-May-2014 14:46:00 +0000
\"
()"
<<
"S: 2 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 2 OK Append completed"
;
QTest
::
newRow
(
"item with existing tags (GID)"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-19"
),
0
);
updateFlags
(
flags
,
QStringList
()
<<
QLatin1String
(
"
\\
SEEN"
)
<<
QLatin1String
(
"$FLAG"
));
updateTags
(
tags
,
{
{
QLatin1String
(
"PLAIN"
),
QLatin1String
(
"TAG-1"
)
},
{
QLatin1String
(
"PLAIN"
),
QLatin1String
(
"TAG-2"
)
}
});
updateNotifcationEntity
(
notification
,
pimItem
);
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
"C: 2 X-AKAPPEND 4 0 (
\\
RemoteId[TEST-19]
\\
MimeType[application/octet-stream]
\\
RemoteRevision[1]
\\
Gid[TEST-19]
\\
Tag[TAG-1]
\\
SEEN
\\
Tag[TAG-2] $FLAG)
\"
12-May-2014 14:46:00 +0000
\"
()"
<<
"S: 2 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 2 OK Append completed"
;
QTest
::
newRow
(
"item with flags and tags"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
updatePimItem
(
pimItem
,
QLatin1String
(
"TEST-20"
),
0
);
updateFlags
(
flags
,
{});
updateTags
(
tags
,
{
{
QLatin1String
(
"PLAIN"
),
utf8String
}
});
updateNotifcationEntity
(
notification
,
pimItem
);;
++
uidnext
;
scenario
.
clear
();
scenario
<<
FakeAkonadiServer
::
defaultScenario
()
<<
"C: 2 X-AKAPPEND 4 0 (
\\
RemoteId[TEST-20]
\\
MimeType[application/octet-stream]
\\
RemoteRevision[1]
\\
Gid[TEST-20]
\\
Tag[äöüß@€µøđ¢©®])
\"
12-May-2014 14:46:00 +0000
\"
()"
<<
"S: 2 [UIDNEXT "
+
QByteArray
::
number
(
uidnext
)
+
" DATETIME
\"
12-May-2014 14:46:00 +0000
\"
]"
<<
"S: 2 OK Append completed"
;
QTest
::
newRow
(
"item with UTF-8 tag"
)
<<
scenario
<<
notification
<<
pimItem
<<
parts
<<
flags
<<
tags
<<
uidnext
<<
datetime
<<
false
;
}
void
testAkAppend
()
{
QFETCH
(
QList
<
QByteArray
>
,
scenario
);
QFETCH
(
NotificationMessageV3
,
notification
);
QFETCH
(
PimItem
,
pimItem
);
QFETCH
(
QVector
<
FakePart
>
,
parts
);
QFETCH
(
QVector
<
Flag
>
,
flags
);
QFETCH
(
QVector
<
FakeTag
>
,
tags
);
QFETCH
(
qint64
,
uidnext
);
QFETCH
(
bool
,
expectFail
);
FakeAkonadiServer
::
instance
()
->
setScenario
(
scenario
);
FakeAkonadiServer
::
instance
()
->
runTest
();
QSignalSpy
*
notificationSpy
=
FakeAkonadiServer
::
instance
()
->
notificationSpy
();
if
(
notification
.
isValid
())
{
QCOMPARE
(
notificationSpy
->
count
(),
1
);
const
NotificationMessageV3
::
List
notifications
=
notificationSpy
->
at
(
0
).
first
().
value
<
NotificationMessageV3
::
List
>
();
QCOMPARE
(
notifications
.
count
(),
1
);
const
NotificationMessageV3
itemNotification
=
notifications
.
first
();
QVERIFY
(
AkTest
::
compareNotifications
(
itemNotification
,
notification
,
QFlag
(
AkTest
::
NtfAll
&
~
AkTest
::
NtfEntities
)));
QCOMPARE
(
itemNotification
.
entities
().
count
(),
notification
.
entities
().
count
());
}
else
{
QVERIFY
(
notificationSpy
->
isEmpty
());
}
const
PimItem
actualItem
=
PimItem
::
retrieveById
(
uidnext
);
if
(
expectFail
)
{
QVERIFY
(
!
actualItem
.
isValid
());
}
else
{
QVERIFY
(
actualItem
.
isValid
());
QCOMPARE
(
actualItem
.
remoteId
(),
pimItem
.
remoteId
());
QCOMPARE
(
actualItem
.
remoteRevision
(),
pimItem
.
remoteRevision
());
QCOMPARE
(
actualItem
.
gid
(),
pimItem
.
gid
());
QCOMPARE
(
actualItem
.
size
(),
pimItem
.
size
());
QCOMPARE
(
actualItem
.
datetime
(),
pimItem
.
datetime
());
QCOMPARE
(
actualItem
.
collectionId
(),
pimItem
.
collectionId
());
QCOMPARE
(
actualItem
.
mimeTypeId
(),
pimItem
.
mimeTypeId
());
const
QList
<
Flag
>
actualFlags
=
actualItem
.
flags
().
toList
();
QCOMPARE
(
actualFlags
.
count
(),
flags
.
count
());
Q_FOREACH
(
const
Flag
&
flag
,
flags
)
{
const
QList
<
Flag
>::
const_iterator
actualFlagIter
=
std
::
find_if
(
actualFlags
.
constBegin
(),
actualFlags
.
constEnd
(),
[
flag
](
Flag
const
&
actualFlag
)
{
return
flag
.
name
()
==
actualFlag
.
name
();
});
QVERIFY
(
actualFlagIter
!=
actualFlags
.
constEnd
());
const
Flag
actualFlag
=
*
actualFlagIter
;
QVERIFY
(
actualFlag
.
isValid
());
}
const
QList
<
Tag
>
actualTags
=
actualItem
.
tags
().
toList
();
QCOMPARE
(
actualTags
.
count
(),
tags
.
count
());
Q_FOREACH
(
const
FakeTag
&
tag
,
tags
)
{
const
QList
<
Tag
>::
const_iterator
actualTagIter
=
std
::
find_if
(
actualTags
.
constBegin
(),
actualTags
.
constEnd
(),
[
tag
](
Tag
const
&
actualTag
)
{
return
tag
.
gid
()
==
actualTag
.
gid
();
});
QVERIFY
(
actualTagIter
!=
actualTags
.
constEnd
());
const
Tag
actualTag
=
*
actualTagIter
;
QVERIFY
(
actualTag
.
isValid
());
QCOMPARE
(
actualTag
.
tagType
().
name
(),
tag
.
tagType
().
name
());
QCOMPARE
(
actualTag
.
gid
(),
tag
.
gid
());
if
(
!
tag
.
remoteId
().
isEmpty
())
{
SelectQueryBuilder
<
TagRemoteIdResourceRelation
>
qb
;
qb
.
addValueCondition
(
TagRemoteIdResourceRelation
::
resourceIdFullColumnName
(),
Query
::
Equals
,
QLatin1String
(
"akonadi_fake_resource_0"
));
qb
.
addValueCondition
(
TagRemoteIdResourceRelation
::
tagIdColumn
(),
Query
::
Equals
,
actualTag
.
id
());
QVERIFY
(
qb
.
exec
());
QCOMPARE
(
qb
.
result
().
size
(),
1
);
QCOMPARE
(
qb
.
result
()[
0
].
remoteId
(),
tag
.
remoteId
());
}
}
const
QList
<
Part
>
actualParts
=
actualItem
.
parts
().
toList
();
QCOMPARE
(
actualParts
.
count
(),
parts
.
count
());
Q_FOREACH
(
const
FakePart
&
part
,
parts
)
{
const
QList
<
Part
>::
const_iterator
actualPartIter
=
std
::
find_if
(
actualParts
.
constBegin
(),
actualParts
.
constEnd
(),
[
part
](
Part
const
&
actualPart
)
{
return
part
.
partType
().
ns
()
==
actualPart
.
partType
().
ns
()
&&
part
.
partType
().
name
()
==
actualPart
.
partType
().
name
();
});
QVERIFY
(
actualPartIter
!=
actualParts
.
constEnd
());
const
Part
actualPart
=
*
actualPartIter
;
QVERIFY
(
actualPart
.
isValid
());
QCOMPARE
(
QString
::
fromUtf8
(
actualPart
.
data
()),
QString
::
fromUtf8
(
part
.
data
()));
QCOMPARE
(
actualPart
.
data
(),
part
.
data
());
QCOMPARE
(
actualPart
.
datasize
(),
part
.
datasize
());
QCOMPARE
(
actualPart
.
external
(),
part
.
external
());
}
}
}
};
AKTEST_FAKESERVER_MAIN
(
AkAppendHandlerTest
)
#include
"akappendhandlertest.moc"
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Fri, Nov 1, 9:50 AM (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
10076169
Default Alt Text
akappendhandlertest.cpp (32 KB)
Attached To
Mode
rA akonadi
Attached
Detach File
Event Timeline
Log In to Comment