File indexing completed on 2024-05-19 04:01:09
0001 /* 0002 SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: MIT 0005 */ 0006 0007 #include "servercontroller.h" 0008 0009 #include <rest/restapi.h> 0010 #include <rest/restclient.h> 0011 0012 #include <core/product.h> 0013 #include <core/schemaentryelement.h> 0014 0015 #include <QDebug> 0016 #include <QtTest/qtest.h> 0017 #include <QNetworkReply> 0018 #include <QObject> 0019 #include <QSignalSpy> 0020 #include <QStandardPaths> 0021 0022 using namespace KUserFeedback::Console; 0023 0024 class ProductApiTest : public QObject 0025 { 0026 Q_OBJECT 0027 private: 0028 ServerController m_server; 0029 0030 ServerInfo testServer() const 0031 { 0032 ServerInfo s; 0033 s.setUrl(m_server.url()); 0034 return s; 0035 } 0036 0037 bool waitForFinished(QNetworkReply *reply) 0038 { 0039 Q_ASSERT(reply); 0040 QSignalSpy spy(reply, &QNetworkReply::finished); 0041 Q_ASSERT(spy.isValid()); 0042 return spy.wait(); 0043 } 0044 0045 Product findProduct(const QVector<Product> &products, const QString &name) 0046 { 0047 const auto it = std::find_if(products.cbegin(), products.cend(), [name](const Product &p) { 0048 return p.name() == name; 0049 }); 0050 if (it != products.cend()) 0051 return *it; 0052 return {}; 0053 } 0054 0055 private Q_SLOTS: 0056 void initTestCase() 0057 { 0058 QStandardPaths::setTestModeEnabled(true); 0059 QVERIFY(m_server.start()); 0060 } 0061 0062 void testInvalidList() 0063 { 0064 RESTClient client; 0065 auto serverInfo = testServer(); 0066 serverInfo.setPassword(QStringLiteral("wrong password")); 0067 client.setServerInfo(serverInfo); 0068 client.setConnected(true); 0069 QVERIFY(client.isConnected()); 0070 0071 auto reply = RESTApi::listProducts(&client); 0072 QVERIFY(waitForFinished(reply)); 0073 QEXPECT_FAIL("", "local PHP tests don't authenticate", Continue); 0074 QVERIFY(reply->error() != QNetworkReply::NoError); 0075 } 0076 0077 void testProductCRUD() 0078 { 0079 RESTClient client; 0080 client.setServerInfo(testServer()); 0081 client.setConnected(true); 0082 QVERIFY(client.isConnected()); 0083 Product newProduct; 0084 newProduct.setName(QStringLiteral("org.kde.UserFeedback.UnitTestProduct")); 0085 0086 // clean up from previous failed runs, if needed 0087 auto reply = RESTApi::deleteProduct(&client, newProduct); 0088 waitForFinished(reply); 0089 0090 // list existing products 0091 reply = RESTApi::listProducts(&client); 0092 QVERIFY(waitForFinished(reply)); 0093 QCOMPARE(reply->error(), QNetworkReply::NoError); 0094 QVERIFY(reply->header(QNetworkRequest::ContentTypeHeader).toString().startsWith(QLatin1String("text/json"))); 0095 const auto products = Product::fromJson(reply->readAll()); 0096 QVERIFY(!findProduct(products, QLatin1String("org.kde.UserFeedback.UnitTestProduct")).isValid()); 0097 0098 // add new product 0099 SchemaEntry entry; 0100 entry.setName(QStringLiteral("entry1")); 0101 SchemaEntryElement elem1; 0102 elem1.setName(QStringLiteral("elem11")); 0103 entry.setElements({elem1}); 0104 newProduct.setSchema({entry}); 0105 QVERIFY(newProduct.isValid()); 0106 reply = RESTApi::createProduct(&client, newProduct); 0107 QVERIFY(waitForFinished(reply)); 0108 QCOMPARE(reply->error(), QNetworkReply::NoError); 0109 0110 // verify the new product is there 0111 reply = RESTApi::listProducts(&client); 0112 QVERIFY(waitForFinished(reply)); 0113 QCOMPARE(reply->error(), QNetworkReply::NoError); 0114 auto newProducts = Product::fromJson(reply->readAll()); 0115 QCOMPARE(newProducts.size(), products.size() + 1); 0116 const auto createdProduct = findProduct(newProducts, QLatin1String("org.kde.UserFeedback.UnitTestProduct")); 0117 QVERIFY(createdProduct.isValid()); 0118 QCOMPARE(createdProduct.schema(), newProduct.schema()); 0119 0120 // update a product 0121 reply = RESTApi::updateProduct(&client, newProduct); 0122 QVERIFY(waitForFinished(reply)); 0123 QCOMPARE(reply->error(), QNetworkReply::NoError); 0124 0125 // try to add an already existing product 0126 reply = RESTApi::createProduct(&client, newProduct); 0127 QVERIFY(waitForFinished(reply)); 0128 QVERIFY(reply->error() != QNetworkReply::NoError); 0129 0130 // verify it really wasn't added 0131 reply = RESTApi::listProducts(&client); 0132 QVERIFY(waitForFinished(reply)); 0133 QCOMPARE(reply->error(), QNetworkReply::NoError); 0134 newProducts = Product::fromJson(reply->readAll()); 0135 QCOMPARE(newProducts.size(), products.size() + 1); 0136 0137 // delete a product 0138 reply = RESTApi::deleteProduct(&client, newProduct); 0139 QVERIFY(waitForFinished(reply)); 0140 QCOMPARE(reply->error(), QNetworkReply::NoError); 0141 0142 // verify it's gone, and nothing else was harmed 0143 reply = RESTApi::listProducts(&client); 0144 QVERIFY(waitForFinished(reply)); 0145 QCOMPARE(reply->error(), QNetworkReply::NoError); 0146 newProducts = Product::fromJson(reply->readAll()); 0147 QCOMPARE(newProducts.size(), products.size()); 0148 QVERIFY(!findProduct(newProducts, QLatin1String("org.kde.UserFeedback.UnitTestProduct")).isValid()); 0149 } 0150 0151 void testInvalidProductOperations() 0152 { 0153 RESTClient client; 0154 client.setServerInfo(testServer()); 0155 client.setConnected(true); 0156 QVERIFY(client.isConnected()); 0157 0158 Product invalidProduct; 0159 invalidProduct.setName(QStringLiteral("org.kde.UserFeedback.Invalid")); 0160 QVERIFY(invalidProduct.isValid()); 0161 0162 // update a non-existing product 0163 auto reply = RESTApi::updateProduct(&client, invalidProduct); 0164 QVERIFY(waitForFinished(reply)); 0165 qDebug() << reply->readAll(); 0166 QVERIFY(reply->error() != QNetworkReply::NoError); 0167 0168 // delete a non-existing product 0169 reply = RESTApi::deleteProduct(&client, invalidProduct); 0170 QVERIFY(waitForFinished(reply)); 0171 QVERIFY(reply->error() != QNetworkReply::NoError); 0172 } 0173 }; 0174 0175 QTEST_MAIN(ProductApiTest) 0176 0177 #include "productapitest.moc"