File indexing completed on 2025-01-19 04:56:54
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Kevin Ottens <ervin@kde.org> 0003 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 */ 0005 0006 0007 #include <testlib/qtest_zanshin.h> 0008 0009 #include "utils/mockobject.h" 0010 0011 #define ZANSHIN_I_SWEAR_I_AM_IN_A_PRESENTATION_TEST 0012 0013 #include "domain/datasourcequeries.h" 0014 #include "domain/datasourcerepository.h" 0015 0016 #include "presentation/availablesourcesmodel.h" 0017 #include "presentation/querytreemodelbase.h" 0018 #include "presentation/errorhandler.h" 0019 0020 #include "testlib/fakejob.h" 0021 0022 Q_DECLARE_METATYPE(QModelIndex); 0023 0024 using namespace mockitopp; 0025 using namespace mockitopp::matcher; 0026 0027 class FakeErrorHandler : public Presentation::ErrorHandler 0028 { 0029 public: 0030 void doDisplayMessage(const QString &message) override 0031 { 0032 m_message = message; 0033 } 0034 0035 QString m_message; 0036 }; 0037 0038 class AvailableSourcesModelTest : public QObject 0039 { 0040 Q_OBJECT 0041 public: 0042 explicit AvailableSourcesModelTest(QObject *parent = nullptr) 0043 : QObject(parent) 0044 { 0045 qRegisterMetaType<QModelIndex>(); 0046 } 0047 0048 private slots: 0049 void shouldListAvailableSources() 0050 { 0051 // GIVEN 0052 0053 // Two top level sources 0054 auto source1 = Domain::DataSource::Ptr::create(); 0055 source1->setName(QStringLiteral("Source 1")); 0056 source1->setIconName(QStringLiteral("foo-icon")); 0057 source1->setSelected(true); 0058 auto source2 = Domain::DataSource::Ptr::create(); 0059 source2->setName(QStringLiteral("Source 2")); 0060 source2->setSelected(false); 0061 source2->setContentTypes(Domain::DataSource::Tasks); 0062 auto topLevelProvider = Domain::QueryResultProvider<Domain::DataSource::Ptr>::Ptr::create(); 0063 auto topLevelResult = Domain::QueryResult<Domain::DataSource::Ptr>::create(topLevelProvider); 0064 topLevelProvider->append(source1); 0065 topLevelProvider->append(source2); 0066 0067 // Two other sources under source1 0068 auto source3 = Domain::DataSource::Ptr::create(); 0069 source3->setName(QStringLiteral("Source 3")); 0070 source3->setSelected(false); 0071 source3->setContentTypes(Domain::DataSource::Tasks); 0072 auto source4 = Domain::DataSource::Ptr::create(); 0073 source4->setSelected(true); 0074 source4->setName(QStringLiteral("Source 4")); 0075 source4->setContentTypes(Domain::DataSource::Tasks); 0076 auto source1Provider = Domain::QueryResultProvider<Domain::DataSource::Ptr>::Ptr::create(); 0077 auto source1Result = Domain::QueryResult<Domain::DataSource::Ptr>::create(source1Provider); 0078 source1Provider->append(source3); 0079 source1Provider->append(source4); 0080 0081 // Nothing under source2, source3 or source4 0082 auto source2Provider = Domain::QueryResultProvider<Domain::DataSource::Ptr>::Ptr::create(); 0083 auto source2Result = Domain::QueryResult<Domain::DataSource::Ptr>::create(source2Provider); 0084 auto source3Provider = Domain::QueryResultProvider<Domain::DataSource::Ptr>::Ptr::create(); 0085 auto source3Result = Domain::QueryResult<Domain::DataSource::Ptr>::create(source3Provider); 0086 auto source4Provider = Domain::QueryResultProvider<Domain::DataSource::Ptr>::Ptr::create(); 0087 auto source4Result = Domain::QueryResult<Domain::DataSource::Ptr>::create(source4Provider); 0088 0089 0090 Utils::MockObject<Domain::DataSourceQueries> sourceQueriesMock; 0091 sourceQueriesMock(&Domain::DataSourceQueries::findTopLevel).when().thenReturn(topLevelResult); 0092 sourceQueriesMock(&Domain::DataSourceQueries::findChildren).when(source1).thenReturn(source1Result); 0093 sourceQueriesMock(&Domain::DataSourceQueries::findChildren).when(source2).thenReturn(source2Result); 0094 sourceQueriesMock(&Domain::DataSourceQueries::findChildren).when(source3).thenReturn(source3Result); 0095 sourceQueriesMock(&Domain::DataSourceQueries::findChildren).when(source4).thenReturn(source4Result); 0096 // We'll simulate a default source change later on 0097 sourceQueriesMock(&Domain::DataSourceQueries::isDefaultSource).when(source1).thenReturn(false); 0098 sourceQueriesMock(&Domain::DataSourceQueries::isDefaultSource).when(source2).thenReturn(true) 0099 .thenReturn(false); 0100 sourceQueriesMock(&Domain::DataSourceQueries::isDefaultSource).when(source3).thenReturn(false); 0101 sourceQueriesMock(&Domain::DataSourceQueries::isDefaultSource).when(source4).thenReturn(false) 0102 .thenReturn(false) 0103 .thenReturn(true); 0104 0105 Utils::MockObject<Domain::DataSourceRepository> sourceRepositoryMock; 0106 0107 Presentation::AvailableSourcesModel sources(sourceQueriesMock.getInstance(), 0108 sourceRepositoryMock.getInstance(), 0109 nullptr); 0110 0111 // WHEN 0112 QAbstractItemModel *model = sources.sourceListModel(); 0113 0114 // THEN 0115 const QModelIndex source1Index = model->index(0, 0); 0116 const QModelIndex source2Index = model->index(1, 0); 0117 const QModelIndex source3Index = model->index(0, 0, source1Index); 0118 const QModelIndex source4Index = model->index(1, 0, source1Index); 0119 0120 QCOMPARE(model->rowCount(), 2); 0121 QCOMPARE(model->rowCount(source1Index), 2); 0122 QCOMPARE(model->rowCount(source2Index), 0); 0123 QCOMPARE(model->rowCount(source3Index), 0); 0124 QCOMPARE(model->rowCount(source4Index), 0); 0125 0126 const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable 0127 | Qt::ItemIsEnabled; 0128 QCOMPARE(model->flags(source1Index), defaultFlags); 0129 QCOMPARE(model->flags(source2Index), defaultFlags | Qt::ItemIsUserCheckable); 0130 QCOMPARE(model->flags(source3Index), defaultFlags | Qt::ItemIsUserCheckable); 0131 QCOMPARE(model->flags(source4Index), defaultFlags | Qt::ItemIsUserCheckable); 0132 0133 QCOMPARE(model->data(source1Index).toString(), source1->name()); 0134 QCOMPARE(model->data(source2Index).toString(), source2->name()); 0135 QCOMPARE(model->data(source3Index).toString(), source3->name()); 0136 QCOMPARE(model->data(source4Index).toString(), source4->name()); 0137 0138 QCOMPARE(model->data(source1Index, Qt::EditRole).toString(), source1->name()); 0139 QCOMPARE(model->data(source2Index, Qt::EditRole).toString(), source2->name()); 0140 QCOMPARE(model->data(source3Index, Qt::EditRole).toString(), source3->name()); 0141 QCOMPARE(model->data(source4Index, Qt::EditRole).toString(), source4->name()); 0142 0143 QVERIFY(!model->data(source1Index, Qt::CheckStateRole).isValid()); 0144 QCOMPARE(model->data(source2Index, Qt::CheckStateRole).toBool(), source2->isSelected()); 0145 QCOMPARE(model->data(source3Index, Qt::CheckStateRole).toBool(), source3->isSelected()); 0146 QCOMPARE(model->data(source4Index, Qt::CheckStateRole).toBool(), source4->isSelected()); 0147 0148 QCOMPARE(model->data(source1Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), source1->iconName()); 0149 QCOMPARE(model->data(source2Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("folder")); 0150 QCOMPARE(model->data(source3Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("folder")); 0151 QCOMPARE(model->data(source4Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("folder")); 0152 0153 QCOMPARE(model->data(source1Index, Presentation::QueryTreeModelBase::IsDefaultRole).toBool(), false); 0154 QCOMPARE(model->data(source2Index, Presentation::QueryTreeModelBase::IsDefaultRole).toBool(), true); 0155 QCOMPARE(model->data(source3Index, Presentation::QueryTreeModelBase::IsDefaultRole).toBool(), false); 0156 QCOMPARE(model->data(source4Index, Presentation::QueryTreeModelBase::IsDefaultRole).toBool(), false); 0157 0158 // WHEN 0159 sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source2).thenReturn(new FakeJob(this)); 0160 sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source4).thenReturn(new FakeJob(this)); 0161 0162 QVERIFY(!model->setData(source1Index, Qt::Unchecked, Qt::CheckStateRole)); 0163 QVERIFY(model->setData(source2Index, Qt::Checked, Qt::CheckStateRole)); 0164 QVERIFY(model->setData(source4Index, Qt::Unchecked, Qt::CheckStateRole)); 0165 0166 // THEN 0167 QVERIFY(sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source2).exactly(1)); 0168 QVERIFY(sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source4).exactly(1)); 0169 0170 QVERIFY(source2->isSelected()); 0171 QVERIFY(!source4->isSelected()); 0172 0173 // WHEN 0174 QSignalSpy spy(model, &QAbstractItemModel::dataChanged); 0175 sourceQueriesMock(&Domain::DataSourceQueries::changeDefaultSource).when(source4).thenReturn(); 0176 sources.setDefaultItem(source4Index); 0177 0178 // THEN 0179 QCOMPARE(model->data(source1Index, Presentation::QueryTreeModelBase::IsDefaultRole).toBool(), false); 0180 QCOMPARE(model->data(source2Index, Presentation::QueryTreeModelBase::IsDefaultRole).toBool(), false); 0181 QCOMPARE(model->data(source3Index, Presentation::QueryTreeModelBase::IsDefaultRole).toBool(), false); 0182 QCOMPARE(model->data(source4Index, Presentation::QueryTreeModelBase::IsDefaultRole).toBool(), true); 0183 0184 // Not overly efficient way of signaling the change, but doesn't happen often 0185 QCOMPARE(spy.count(), 4); 0186 QCOMPARE(spy.at(0).at(0).toModelIndex(), source1Index); 0187 QCOMPARE(spy.at(0).at(1).toModelIndex(), source1Index); 0188 QCOMPARE(spy.at(1).at(0).toModelIndex(), source3Index); 0189 QCOMPARE(spy.at(1).at(1).toModelIndex(), source3Index); 0190 QCOMPARE(spy.at(2).at(0).toModelIndex(), source4Index); 0191 QCOMPARE(spy.at(2).at(1).toModelIndex(), source4Index); 0192 QCOMPARE(spy.at(3).at(0).toModelIndex(), source2Index); 0193 QCOMPARE(spy.at(3).at(1).toModelIndex(), source2Index); 0194 0195 QVERIFY(sourceQueriesMock(&Domain::DataSourceQueries::changeDefaultSource).when(source4).exactly(1)); 0196 } 0197 0198 void shouldGetAnErrorMessageWhenSetDataSourceFailed() 0199 { 0200 // GIVEN 0201 0202 // Two top level sources 0203 auto source1 = Domain::DataSource::Ptr::create(); 0204 source1->setName(QStringLiteral("Source 1")); 0205 source1->setIconName(QStringLiteral("foo-icon")); 0206 source1->setSelected(false); 0207 source1->setContentTypes(Domain::DataSource::Tasks); 0208 auto topLevelProvider = Domain::QueryResultProvider<Domain::DataSource::Ptr>::Ptr::create(); 0209 auto topLevelResult = Domain::QueryResult<Domain::DataSource::Ptr>::create(topLevelProvider); 0210 topLevelProvider->append(source1); 0211 0212 // Nothing under source1 0213 auto source1Provider = Domain::QueryResultProvider<Domain::DataSource::Ptr>::Ptr::create(); 0214 auto source1Result = Domain::QueryResult<Domain::DataSource::Ptr>::create(source1Provider); 0215 0216 Utils::MockObject<Domain::DataSourceQueries> sourceQueriesMock; 0217 sourceQueriesMock(&Domain::DataSourceQueries::findTopLevel).when().thenReturn(topLevelResult); 0218 sourceQueriesMock(&Domain::DataSourceQueries::findChildren).when(source1).thenReturn(source1Result); 0219 0220 Utils::MockObject<Domain::DataSourceRepository> sourceRepositoryMock; 0221 0222 Presentation::AvailableSourcesModel sources(sourceQueriesMock.getInstance(), 0223 sourceRepositoryMock.getInstance(), 0224 nullptr); 0225 FakeErrorHandler errorHandler; 0226 sources.setErrorHandler(&errorHandler); 0227 0228 // WHEN 0229 QAbstractItemModel *model = sources.sourceListModel(); 0230 0231 // THEN 0232 const QModelIndex source1Index = model->index(0, 0); 0233 0234 // WHEN 0235 auto job = new FakeJob(this); 0236 job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); 0237 sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source1).thenReturn(job); 0238 0239 QVERIFY(model->setData(source1Index, Qt::Unchecked, Qt::CheckStateRole)); 0240 0241 // THEN 0242 QTest::qWait(150); 0243 QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify source Source 1: Foo")); 0244 } 0245 0246 void shouldExecBackendSettingsDialog() 0247 { 0248 // GIVEN 0249 Utils::MockObject<Domain::DataSourceRepository> sourceRepositoryMock; 0250 sourceRepositoryMock(&Domain::DataSourceRepository::showConfigDialog).when().thenReturn(); 0251 0252 Presentation::AvailableSourcesModel sources(Domain::DataSourceQueries::Ptr(), 0253 sourceRepositoryMock.getInstance()); 0254 0255 // WHEN 0256 sources.showConfigDialog(); 0257 0258 // THEN 0259 QVERIFY(sourceRepositoryMock(&Domain::DataSourceRepository::showConfigDialog).when().exactly(1)); 0260 } 0261 }; 0262 0263 ZANSHIN_TEST_MAIN(AvailableSourcesModelTest) 0264 0265 #include "availablesourcesmodeltest.moc"