// Copyright (C) 2017 Witekio. // Copyright (C) 2018 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include #include #include class tst_QCoapMessage : public QObject { Q_OBJECT private Q_SLOTS: void copyAndDetach(); void setType_data(); void setType(); void addOption(); void addOption_string_data(); void addOption_string(); void addOption_uint_data(); void addOption_uint(); void removeOption_data(); void removeOption(); void removeOptionByName_data(); void removeOptionByName(); void removeAll(); }; void tst_QCoapMessage::copyAndDetach() { QCoapMessage a; a.setMessageId(3); a.setPayload("payload"); a.setToken("token"); a.setType(QCoapMessage::Type::Acknowledgment); a.setVersion(5); // Test the copy QCoapMessage b(a); QVERIFY2(b.messageId() == 3, "Message not copied correctly"); QVERIFY2(b.payload() == "payload", "Message not copied correctly"); QVERIFY2(b.token() == "token", "Message not copied correctly"); QVERIFY2(b.type() == QCoapMessage::Type::Acknowledgment, "Message not copied correctly"); QVERIFY2(b.version() == 5, "Message not copied correctly"); // Detach b.setMessageId(9); QCOMPARE(b.messageId(), 9); QCOMPARE(a.messageId(), 3); } void tst_QCoapMessage::setType_data() { QTest::addColumn("type"); QTest::newRow("acknowledgment") << QCoapMessage::Type::Acknowledgment; QTest::newRow("confirmable") << QCoapMessage::Type::Confirmable; QTest::newRow("non-confirmable") << QCoapMessage::Type::NonConfirmable; QTest::newRow("reset") << QCoapMessage::Type::Reset; } void tst_QCoapMessage::setType() { QFETCH(QCoapMessage::Type, type); QCoapMessage message; message.setType(type); QCOMPARE(message.type(), type); } void tst_QCoapMessage::addOption() { QCoapMessage message; QList optionNames = { QCoapOption::ProxyUri, QCoapOption::UriHost, QCoapOption::LocationQuery, QCoapOption::ProxyUri, QCoapOption::UriHost, QCoapOption::UriQuery }; QVERIFY(!std::is_sorted(optionNames.cbegin(), optionNames.cend())); const QByteArray value("\xAF\x01\xC2"); for (const auto& name : optionNames) message.addOption(name, value); QCOMPARE(message.optionCount(), optionNames.size()); QVERIFY(std::is_sorted(message.options().cbegin(), message.options().cend(), [](const QCoapOption &a, const QCoapOption &b) -> bool { return a.name() < b.name(); })); for (const auto& name : optionNames) QVERIFY2(message.hasOption(name), qPrintable(QString("Missing option %1").arg(name))); QVERIFY(std::all_of(message.options().cbegin(), message.options().cend(), [value](const QCoapOption opt) -> bool { return opt.opaqueValue() == value; })); } void tst_QCoapMessage::addOption_string_data() { QTest::addColumn>("options"); QList single_string_option = { { QCoapOption::LocationPath, QString("path1") } }; QList single_ba_option = { { QCoapOption::LocationPath, QByteArray("\xAF\x01\xC2") } }; QList multiple_string_options = { { QCoapOption::LocationPath, QString("str_path2") }, { QCoapOption::LocationPath, QString("str_path3") } }; QTest::newRow("single_char_option") << single_string_option; QTest::newRow("single_ba_option") << single_ba_option; QTest::newRow("multiple_string_options") << multiple_string_options; } void tst_QCoapMessage::addOption_string() { QFETCH(QList, options); QCoapMessage message; for (const auto& option : options) message.addOption(option); QCOMPARE(message.optionCount(), options.size()); for (const auto& option : options) { const auto it = std::find(message.options().cbegin(), message.options().cend(), option); QVERIFY(it != message.options().cend()); } } void tst_QCoapMessage::addOption_uint_data() { QTest::addColumn("value"); QTest::addColumn("size"); QTest::newRow("4 bytes") << static_cast(0xF0aF0010) << 4; QTest::newRow("3 bytes") << static_cast(0x300010) << 3; QTest::newRow("2 bytes") << static_cast(0x5010) << 2; QTest::newRow("1 byte") << static_cast(0x80) << 1; } void tst_QCoapMessage::addOption_uint() { QFETCH(quint32, value); QFETCH(int, size); const auto name = QCoapOption::Block1; const QCoapOption option(name, value); QCoapMessage message; message.addOption(option); QCOMPARE(message.options(name).size(), 1); QCOMPARE(message.option(name).uintValue(), value); QCOMPARE(option.opaqueValue().size(), size); } void tst_QCoapMessage::removeOption_data() { QTest::addColumn>("options"); QList single_option = { { QCoapOption::LocationPath, QByteArray("path1") } }; QList multiple_options = { { QCoapOption::LocationPath, QByteArray("path2") }, { QCoapOption::LocationPath, QByteArray("path3") } }; QTest::newRow("single_option") << single_option; QTest::newRow("multiple_options") << multiple_options; } void tst_QCoapMessage::removeOption() { QFETCH(QList, options); QCoapMessage message; for (const auto& option : options) message.addOption(option); for (const auto& option : options) { // Make sure option is present before removal auto it = std::find(message.options().cbegin(), message.options().cend(), option); QVERIFY(it != message.options().end()); message.removeOption(option); it = std::find(message.options().cbegin(), message.options().cend(), option); QVERIFY(it == message.options().end()); } } void tst_QCoapMessage::removeOptionByName_data() { QTest::addColumn>("options"); QTest::addColumn("name"); QList single_option = { { QCoapOption::LocationPath, QByteArray("path1") } }; QList multiple_options = { { QCoapOption::LocationPath, QByteArray("path2") }, { QCoapOption::LocationPath, QByteArray("path3") } }; QTest::newRow("remove_single_option") << single_option << single_option.back().name(); QTest::newRow("remove_multiple_options") << multiple_options << multiple_options.back().name(); } void tst_QCoapMessage::removeOptionByName() { QFETCH(QList, options); QFETCH(QCoapOption::OptionName, name); QCoapMessage message; for (const auto& option : options) message.addOption(option); message.removeOption(name); QVERIFY(!message.hasOption(name)); } void tst_QCoapMessage::removeAll() { QCoapMessage message; message.addOption(QCoapOption::LocationPath, "path"); message.addOption(QCoapOption::ProxyUri, "proxy1"); message.addOption(QCoapOption::ProxyUri, "proxy2"); message.clearOptions(); QVERIFY(message.options().isEmpty()); } QTEST_APPLESS_MAIN(tst_QCoapMessage) #include "tst_qcoapmessage.moc"