1/****************************************************************************
2**
3** Copyright (C) 2015 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL21$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 or version 3 as published by the Free
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22** following information to ensure the GNU Lesser General Public License
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25**
26** As a special exception, The Qt Company gives you certain additional
27** rights. These rights are described in The Qt Company LGPL Exception
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29**
30** $QT_END_LICENSE$
31**
32****************************************************************************/
33
34//TESTED_COMPONENT=src/versit
35
36#include "tst_qvcard30writer.h"
37#ifdef QT_BUILD_INTERNAL
38#include <QtVersit/private/qvcard30writer_p.h>
39#endif
40#include <QtVersit/qversitdocument.h>
41#include <QtVersit/qversitproperty.h>
42#include <QtTest/QtTest>
43#include <QByteArray>
44#include <QVariant>
45
46// This says "NOKIA" in Katakana encoded with UTF-8
47const QString KATAKANA_NOKIA(QString::fromUtf8(str: "\xe3\x83\x8e\xe3\x82\xad\xe3\x82\xa2"));
48
49QTVERSIT_USE_NAMESPACE
50
51Q_DECLARE_METATYPE(QVersitProperty)
52#ifdef QT_BUILD_INTERNAL
53void tst_QVCard30Writer::init()
54{
55 mWriter = new QVCard30Writer(QVersitDocument::VCard30Type);
56 mWriter->setCodec(QTextCodec::codecForName(name: "UTF-8"));
57}
58
59void tst_QVCard30Writer::cleanup()
60{
61 delete mWriter;
62}
63
64void tst_QVCard30Writer::testEncodeVersitProperty()
65{
66 QFETCH(QVersitProperty, property);
67 QFETCH(QByteArray, expectedResult);
68 QByteArray encodedProperty;
69 QBuffer buffer(&encodedProperty);
70 mWriter->setDevice(&buffer);
71 buffer.open(openMode: QIODevice::WriteOnly);
72 mWriter->encodeVersitProperty(property);
73 QCOMPARE(encodedProperty, expectedResult);
74}
75
76
77void tst_QVCard30Writer::testEncodeVersitProperty_data()
78{
79 QTest::addColumn<QVersitProperty>(name: "property");
80 QTest::addColumn<QByteArray>(name: "expectedResult");
81
82 QVersitProperty property;
83 QByteArray expectedResult;
84
85 // No parameters
86 expectedResult = "FN:John Citizen\r\n";
87 property.setName(QString::fromLatin1(str: "FN"));
88 property.setValue(QString::fromLatin1(str: "John Citizen"));
89 QTest::newRow(dataTag: "No parameters") << property << expectedResult;
90
91 // With parameter(s)
92 expectedResult = "TEL;TYPE=HOME:123\r\n";
93 property.setName(QString::fromLatin1(str: "TEL"));
94 property.setValue(QString::fromLatin1(str: "123"));
95 property.insertParameter(name: QString::fromLatin1(str: "TYPE"),value: QString::fromLatin1(str: "HOME"));
96 QTest::newRow(dataTag: "With parameters, plain value") << property << expectedResult;
97
98 // normal FN property is backslash escaped
99 property.clear();
100 property.setName(QStringLiteral("FN"));
101 property.setValue(QStringLiteral(";,:\\"));
102 // semicolons, commas and backslashes are escaped (not colons, as per RFC2426)
103 expectedResult = "FN:\\;\\,:\\\\\r\n";
104 QTest::newRow(dataTag: "FN property") << property << expectedResult;
105
106 // Structured N
107 property.setName(QStringLiteral("N"));
108 property.setValue(QStringList()
109 << QStringLiteral("La;st") // needs to be backslash escaped
110 << QStringLiteral("Fi,rst")
111 << QStringLiteral("Mi:ddle")
112 << QStringLiteral("Pr\\efix") // needs to be QP encoded
113 << QStringLiteral("Suffix"));
114 property.setValueType(QVersitProperty::CompoundType);
115 expectedResult = "N:La\\;st;Fi\\,rst;Mi:ddle;Pr\\\\efix;Suffix\r\n";
116 QTest::newRow(dataTag: "N property") << property << expectedResult;
117
118 // Structured CATEGORIES
119 property.setName(QStringLiteral("CATEGORIES"));
120 property.setValue(QStringList()
121 << QStringLiteral("re;d")
122 << QStringLiteral("gr,een")
123 << QStringLiteral("bl:ue")
124 << QStringLiteral("ye\\llow"));
125 property.setValueType(QVersitProperty::ListType);
126 expectedResult = "CATEGORIES:re\\;d,gr\\,een,bl:ue,ye\\\\llow\r\n";
127 QTest::newRow(dataTag: "CATEGORIES property") << property << expectedResult;
128
129 // Convert X-NICKNAME to NICKNAME
130 expectedResult = "NICKNAME:Jack\r\n";
131 property.setParameters(QMultiHash<QString,QString>());
132 property.setName(QString::fromLatin1(str: "X-NICKNAME"));
133 property.setValue(QString::fromLatin1(str: "Jack"));
134 QTest::newRow(dataTag: "NICKNAME property") << property << expectedResult;
135
136 // Convert X-IMPP to IMPP;
137 expectedResult = "IMPP:msn:msn-address\r\n";
138 property.setParameters(QMultiHash<QString,QString>());
139 property.setName(QString::fromLatin1(str: "X-IMPP"));
140 property.setValue(QString::fromLatin1(str: "msn:msn-address"));
141 QTest::newRow(dataTag: "IMPP property") << property << expectedResult;
142
143 // AGENT property
144 expectedResult = "AGENT:BEGIN:VCARD\\nVERSION:3.0\\nFN:Secret Agent\\nEND:VCARD\\n\r\n";
145 property.setName(QString::fromLatin1(str: "AGENT"));
146 property.setValue(QString());
147 QVersitDocument document(QVersitDocument::VCard30Type);
148 document.setComponentType(QStringLiteral("VCARD"));
149 QVersitProperty embeddedProperty;
150 embeddedProperty.setName(QString(QString::fromLatin1(str: "FN")));
151 embeddedProperty.setValue(QString::fromLatin1(str: "Secret Agent"));
152 document.addProperty(property: embeddedProperty);
153 property.setValue(QVariant::fromValue(value: document));
154 QTest::newRow(dataTag: "AGENT property") << property << expectedResult;
155
156 // Value is base64 encoded.
157 QByteArray value("value");
158 expectedResult = "Springfield.HOUSE.PHOTO;ENCODING=b:" + value.toBase64() + "\r\n";
159 QStringList groups(QString::fromLatin1(str: "Springfield"));
160 groups.append(t: QString::fromLatin1(str: "HOUSE"));
161 property.setGroups(groups);
162 property.setParameters(QMultiHash<QString,QString>());
163 property.setName(QString::fromLatin1(str: "PHOTO"));
164 property.setValue(value);
165 QTest::newRow(dataTag: "base64 encoded") << property << expectedResult;
166
167 // Characters other than ASCII:
168 expectedResult = "ORG:" + KATAKANA_NOKIA.toUtf8() + "\r\n";
169 property = QVersitProperty();
170 property.setName(QStringLiteral("ORG"));
171 property.setValue(KATAKANA_NOKIA);
172 QTest::newRow(dataTag: "non-ASCII") << property << expectedResult;
173
174 // No CHARSET and QUOTED-PRINTABLE parameters
175 expectedResult = "EMAIL:john@" + KATAKANA_NOKIA.toUtf8() + ".com\r\n";
176 property = QVersitProperty();
177 property.setName(QStringLiteral("EMAIL"));
178 property.setValue(QString::fromLatin1(str: "john@%1.com").arg(a: KATAKANA_NOKIA));
179 QTest::newRow(dataTag: "special chars") << property << expectedResult;
180}
181
182void tst_QVCard30Writer::testEncodeParameters()
183{
184 QByteArray encodedParameters;
185 QBuffer buffer(&encodedParameters);
186 mWriter->setDevice(&buffer);
187 buffer.open(openMode: QIODevice::WriteOnly);
188
189 QString typeParameterName(QString::fromLatin1(str: "TYPE"));
190 QString encodingParameterName(QString::fromLatin1(str: "ENCODING"));
191
192 // No parameters
193 QMultiHash<QString,QString> parameters;
194 mWriter->encodeParameters(parameters);
195 QCOMPARE(encodedParameters, QByteArray(""));
196
197 // One TYPE parameter
198 parameters.insert(akey: typeParameterName,avalue: QString::fromLatin1(str: "HOME"));
199 mWriter->writeCrlf(); // so it doesn't start folding
200 buffer.close();
201 encodedParameters.clear();
202 buffer.open(openMode: QIODevice::WriteOnly);
203 mWriter->encodeParameters(parameters);
204 QCOMPARE(encodedParameters, QByteArray(";TYPE=HOME"));
205
206 // Two TYPE parameters
207 parameters.insert(akey: typeParameterName,avalue: QString::fromLatin1(str: "VOICE"));
208 mWriter->writeCrlf(); // so it doesn't start folding
209 buffer.close();
210 encodedParameters.clear();
211 buffer.open(openMode: QIODevice::WriteOnly);
212 mWriter->encodeParameters(parameters);
213 QCOMPARE(encodedParameters, QByteArray(";TYPE=VOICE,HOME"));
214
215 // One ENCODING parameter
216 parameters.clear();
217 parameters.insert(akey: encodingParameterName,avalue: QString::fromLatin1(str: "8BIT"));
218 mWriter->writeCrlf(); // so it doesn't start folding
219 buffer.close();
220 encodedParameters.clear();
221 buffer.open(openMode: QIODevice::WriteOnly);
222 mWriter->encodeParameters(parameters);
223 QCOMPARE(encodedParameters, QByteArray(";ENCODING=8BIT"));
224
225 // Two parameters
226 parameters.insert(akey: QString::fromLatin1(str: "X-PARAM"),avalue: QString::fromLatin1(str: "VALUE"));
227 mWriter->writeCrlf(); // so it doesn't start folding
228 buffer.close();
229 encodedParameters.clear();
230 buffer.open(openMode: QIODevice::WriteOnly);
231 mWriter->encodeParameters(parameters);
232 QCOMPARE(encodedParameters, QByteArray(";ENCODING=8BIT;X-PARAM=VALUE"));
233
234 // Parameter with characters that require backslash escaping
235 parameters.clear();
236 parameters.insert(akey: QString::fromLatin1(str: "X-P;ARAM"),avalue: QString::fromLatin1(str: "VA,LUE"));
237 mWriter->writeCrlf(); // so it doesn't start folding
238 buffer.close();
239 encodedParameters.clear();
240 buffer.open(openMode: QIODevice::WriteOnly);
241 mWriter->encodeParameters(parameters);
242 QCOMPARE(encodedParameters, QByteArray(";X-P\\;ARAM=VA\\,LUE"));
243}
244
245void tst_QVCard30Writer::testBackSlashEscape()
246{
247 // Empty string
248 QString input;
249 QVCard30Writer::backSlashEscape(text: &input);
250 QCOMPARE(input,QString());
251
252 // Nothing to escape in the string
253 input = QString::fromLatin1(str: "Nothing to escape");
254 QVCard30Writer::backSlashEscape(text: &input);
255 QCOMPARE(input,QString::fromLatin1("Nothing to escape"));
256
257 // Line break in the beginning
258 input = QString::fromLatin1(str: "\r\n input");
259 QVCard30Writer::backSlashEscape(text: &input);
260 QCOMPARE(input,QString::fromLatin1("\\n input"));
261
262 // Line break in the end
263 input = QString::fromLatin1(str: "input\r\n");
264 QVCard30Writer::backSlashEscape(text: &input);
265 QCOMPARE(input,QString::fromLatin1("input\\n"));
266
267 // Semicolon in the beginning
268 input = QString::fromLatin1(str: ";input");
269 QVCard30Writer::backSlashEscape(text: &input);
270 QCOMPARE(input,QString::fromLatin1("\\;input"));
271
272 // Semicolon in the end
273 input = QString::fromLatin1(str: "input;");
274 QVCard30Writer::backSlashEscape(text: &input);
275 QCOMPARE(input,QString::fromLatin1("input\\;"));
276
277 // Comma in the beginning
278 input = QString::fromLatin1(str: ",input");
279 QVCard30Writer::backSlashEscape(text: &input);
280 QCOMPARE(input,QString::fromLatin1("\\,input"));
281
282 // Comma in the end
283 input = QString::fromLatin1(str: "input,");
284 QVCard30Writer::backSlashEscape(text: &input);
285 QCOMPARE(input,QString::fromLatin1("input\\,"));
286
287 // Backslash in the beginning
288 input = QString::fromLatin1(str: "\\input");
289 QVCard30Writer::backSlashEscape(text: &input);
290 QCOMPARE(input,QString::fromLatin1("\\\\input"));
291
292 // Backslash in the end
293 input = QString::fromLatin1(str: "input\\");
294 QVCard30Writer::backSlashEscape(text: &input);
295 QCOMPARE(input,QString::fromLatin1("input\\\\"));
296
297 // Line break, semicolon, backslash and comma in the middle of the string
298 input = QString::fromLatin1(str: "Escape these \r\n ; , \\ ");
299 QVCard30Writer::backSlashEscape(text: &input);
300 QCOMPARE(input, QString::fromLatin1("Escape these \\n \\; \\, \\\\ "));
301}
302#endif
303QTEST_MAIN(tst_QVCard30Writer)
304
305

source code of qtpim/tests/auto/versit/qvcard30writer/tst_qvcard30writer.cpp