/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
#include "t_tsmodel.h"
#include <qservicemanager.h>
#include <QtTest/QtTest>
#include "tsmodel.h"
#include "afmanager.h"
#include <afstorageglobals.h>
#include "tstaskchangeinfo.h"
#include <hbicon.h>
#define TSTASKMONITOR_TEST 1
const int dataSetsCount(50);
const char serviceName [] = "TestActivityService";
const char ActivityIconKeyword [] = "screenshot";
const char ActivityVisibleKeyword [] = "visible";
//TEST CASES
void T_TsModel::testData()
{
QVERIFY(mModel);
QVERIFY(activityService());
for (int dataSet(0); dataSet < activityDataSetsCount(); ++dataSet) {
QList<QVariantHash>data(activityDataSet(dataSet));
//provide test data to TestActivityManager
QMetaObject::invokeMethod(activityService(),
"setActivitiesList",
Q_ARG(QList<QVariantHash>, data));
QList<TsTaskChange> applications(appDataSetFull(dataSet));
QMetaObject::invokeMethod(mAppSrv,
"setTaskList",
Q_ARG(QList<TsTaskChange>, applications));
//force data update on model. framework doesnt provide observer functionality
mModel->fullUpdate();
int offset =0;
//Verify data. Applications come first...
foreach ( TsTaskChange application, applications) {
if(application.first.changeType() == TsTaskChangeInfo::EChangeCancel ) {
continue;
}
QVERIFY(application.second->name() == mModel->data(mModel->index(offset), Qt::DisplayRole).toString());
//icon can't be realy checked, but can be called
mModel->data(mModel->index(offset), Qt::DecorationRole);
QVERIFY(application.second->isClosable() == mModel->data(mModel->index(offset), Qt::UserRole + 1).toBool());//is closable
QVERIFY(!mModel->data(mModel->index(offset), Qt::UserRole + 100).isValid());//call some unsupported role
++offset;//move to next model row
}
//Activity come second
QList<QVariantHash>::const_iterator activity(data.begin());
for (; activity != data.end(); ++activity) {
QString debstr = mModel->data(mModel->index(offset), Qt::DisplayRole).toString();
QVERIFY(0>=mModel->data(mModel->index(offset), Qt::DisplayRole).toString().length());
//icon can't be realy checked, but can be called
mModel->data(mModel->index(offset), Qt::DecorationRole);
QVERIFY(!mModel->data(mModel->index(offset), Qt::UserRole + 1).toBool());//is closable
QVERIFY(!mModel->data(mModel->index(offset), Qt::UserRole + 100).isValid());//call some unsupported role
++offset;//move to next model row
}
//call data out of range
QVERIFY(!mModel->data(mModel->index(-1), Qt::DisplayRole).isValid());
}
}
void T_TsModel::testRowCount()
{
QVERIFY(mModel);
QVERIFY(activityService());
for (int dataSet(0); dataSet < activityDataSetsCount(); ++dataSet) {
QList<QVariantHash> activity(activityDataSet(dataSet));
//provide test data to TestActivityManager
QMetaObject::invokeMethod(activityService(),
"setActivitiesList",
Q_ARG(QList<QVariantHash>, activity));
QList<TsTaskChange> applications(appDataSetFull(dataSet));
//provide test data to TestActivityManager
QMetaObject::invokeMethod(mAppSrv,
"setTaskList",
Q_ARG(QList<TsTaskChange>, applications));
//force data update on model. framework doesnt provide observer functionality
mModel->fullUpdate();
QVERIFY(mModel->rowCount() <= (activity.count() + applications.count()));
}
}
void T_TsModel::testOpenApplication()
{
QMetaObject::invokeMethod(activityService(),
"setActivitiesList",
Q_ARG(QList<QVariantHash>, activityDataSet(1)));
mModel->fullUpdate();
for (int i =0; i < mModel->rowCount(); ++i) {
mModel->openApplication(mModel->index(i));//just call without veryfication
}
mModel->openApplication(mModel->index(-1));//just call without veryfication
}
void T_TsModel::testCloseApplication()
{
QMetaObject::invokeMethod(activityService(),
"setActivitiesList",
Q_ARG(QList<QVariantHash>, activityDataSet(1)));
mModel->fullUpdate();
for (int i =0; i < mModel->rowCount(); ++i) {
mModel->closeApplication(mModel->index(i));//just call without veryfication
}
mModel->closeApplication(mModel->index(-1));//just call without veryfication
}
void T_TsModel::testActivityWithNoIdDisplaysProperApplicationName()
{
// prepare activity entry with no activity ID, but with proper application name
QVariantHash activity;
RProcess process;
activity.insert(ActivityApplicationKeyword, static_cast<int>(process.SecureId().iId));
// prepare data set with only prepared activity
QVERIFY(QMetaObject::invokeMethod(activityService(),
"setActivitiesList",
Q_ARG(QList<QVariantHash>, QList<QVariantHash>() << activity)));
QVERIFY(QMetaObject::invokeMethod(mAppSrv,
"setTaskList",
Q_ARG(QList<TsTaskChange>, QList<TsTaskChange>())));
mModel->fullUpdate();
// verify the application name is correctly returned as a DisplayRole
QCOMPARE(mModel->rowCount(), 1);
QVERIFY(mModel->index(0).isValid());
QVERIFY(!mModel->data(mModel->index(0), Qt::DisplayRole).toString().isEmpty());
}
void T_TsModel::testDataChangedSignalIsEmittedWhenActivityScreenshotIsUpdated()
{
// prepare activity entry
QVariantHash activity;
activity.insert(ActivityIconKeyword, "FakeScreenshotPath");
// prepare data set with only prepared activity
QVERIFY(QMetaObject::invokeMethod(activityService(),
"setActivitiesList",
Q_ARG(QList<QVariantHash>, QList<QVariantHash>() << activity)));
QVERIFY(QMetaObject::invokeMethod(mAppSrv,
"setTaskList",
Q_ARG(QList<TsTaskChange>, QList<TsTaskChange>())));
mModel->fullUpdate();
// prepare signal spy
qRegisterMetaType<QModelIndex>("QModelIndex");
QSignalSpy spy(mModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)));
QVERIFY(spy.isValid());
// getting the decoration role should trigger asynchronous screenshot retrieval and dataChanged signal emission
QCOMPARE(mModel->rowCount(), 1);
QVERIFY(mModel->index(0).isValid());
mModel->data(mModel->index(0), Qt::DecorationRole);
// verify proper data passed in signal
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.first().at(0).value<QModelIndex>().row(), 0);
QCOMPARE(spy.first().at(1).value<QModelIndex>().row(), 0);
}
void T_TsModel::testCustomNameIsUsedIfPresent()
{
RProcess process;
int applicationId = static_cast<int>(process.SecureId().iId);
// prepare activity entries
QVariantHash activityWithCustomName;
activityWithCustomName.insert(ActivityApplicationName, "Custom Activity Name");
activityWithCustomName.insert(ActivityApplicationKeyword, applicationId);
QVariantHash otherActivity;
otherActivity.insert(ActivityApplicationKeyword, applicationId);
// prepare data set with only prepared activities
QVERIFY(QMetaObject::invokeMethod(activityService(),
"setActivitiesList",
Q_ARG(QList<QVariantHash>, QList<QVariantHash>() << activityWithCustomName << otherActivity)));
QVERIFY(QMetaObject::invokeMethod(mAppSrv,
"setTaskList",
Q_ARG(QList<TsTaskChange>, QList<TsTaskChange>())));
mModel->fullUpdate();
// first activity uses custom name
QCOMPARE(mModel->rowCount(), 2);
QCOMPARE(mModel->data(mModel->index(0), Qt::DisplayRole), QVariant("Custom Activity Name"));
// second one didn't define custom name, so it uses application name
QVERIFY(!mModel->data(mModel->index(1), Qt::DisplayRole).toString().isEmpty());
}
void T_TsModel::testInsert1()
{
QVERIFY(mModel);
clearModel();
QVERIFY(QMetaObject::invokeMethod(mAppSrv,
"setTaskList",
Q_ARG(QList<TsTaskChange>, changeDataSet5New())));
QCOMPARE(mModel->rowCount(), 5);
QVERIFY(QMetaObject::invokeMethod(mAppSrv,
"setTaskList",
Q_ARG(QList<TsTaskChange>, changeDataSetInsert1(3))));
QCOMPARE(mModel->rowCount(), 6);
QVERIFY(changeDataSetInsert1(3)[0].second->name() == mModel->data(mModel->index(3), Qt::DisplayRole).toString());
}
void T_TsModel::testDelete1()
{
QVERIFY(mModel);
clearModel();
QVERIFY(QMetaObject::invokeMethod(mAppSrv,
"setTaskList",
Q_ARG(QList<TsTaskChange>, changeDataSet5New())));
QCOMPARE(mModel->rowCount(), 5);
QVERIFY(QMetaObject::invokeMethod(mAppSrv,
"setTaskList",
Q_ARG(QList<TsTaskChange>, changeDataSetDelete1(1))));
QCOMPARE(mModel->rowCount(), 4);
QCOMPARE(changeDataSet5New()[3].second->name(), mModel->data(mModel->index(1), Qt::DisplayRole).toString());
}
void T_TsModel::testChange1()
{
QVERIFY(mModel);
clearModel();
QVERIFY(QMetaObject::invokeMethod(mAppSrv,
"setTaskList",
Q_ARG(QList<TsTaskChange>, changeDataSet5New())));
QCOMPARE(mModel->rowCount(), 5);
QVERIFY(QMetaObject::invokeMethod(mAppSrv,
"setTaskList",
Q_ARG(QList<TsTaskChange>, changeDataSetChange1(2))));
QCOMPARE(mModel->rowCount(), 5);
QCOMPARE(changeDataSetChange1(2)[0].second->name(), mModel->data(mModel->index(2), Qt::DisplayRole).toString());
}
void T_TsModel::testMove1()
{
QVERIFY(mModel);
clearModel();
QVERIFY(QMetaObject::invokeMethod(mAppSrv,
"setTaskList",
Q_ARG(QList<TsTaskChange>, changeDataSet5New())));
QCOMPARE(mModel->rowCount(), 5);
QVERIFY(QMetaObject::invokeMethod(mAppSrv,
"setTaskList",
Q_ARG(QList<TsTaskChange>, changeDataSetMove1(1,2))));
QCOMPARE(mModel->rowCount(), 5);
QCOMPARE(changeDataSet5New()[2].second->name(), mModel->data(mModel->index(2), Qt::DisplayRole).toString());
QCOMPARE(changeDataSet5New()[3].second->name(), mModel->data(mModel->index(1), Qt::DisplayRole).toString());
}
void T_TsModel::testFullUpdateFromActivities()
{
QVERIFY(mModel);
QVERIFY(activityService());
clearModel();
QList<QVariantHash> activity(activityDataSet(5));
//provide test data to TestActivityManager
QMetaObject::invokeMethod(activityService(),
"setActivitiesList",
Q_ARG(QList<QVariantHash>, activity));
QMetaObject::invokeMethod(activityService(),
"emitDataChanged");
QCOMPARE(mModel->rowCount(), 5);
}
//QTEST CALLBACKS
void T_TsModel::initTestCase()
{
mAppSrv = new MockTsTaskMonitor();
mActSrv = new AfManager();
QVERIFY(mAppSrv);
QVERIFY(mActSrv);
mModel = new TsModel(*mAppSrv, *mActSrv);
QVERIFY(mModel);
}
void T_TsModel::cleanupTestCase()
{
delete mModel;
mModel = 0;
delete mActSrv;
mActSrv = 0;
QtMobility::QServiceManager manager;
manager.removeService(serviceName);
delete mAppSrv;
}
// HELPER FUNCTIONS
QObject *T_TsModel::activityService()
{
return mActSrv;
}
QList<QVariantHash> T_TsModel::activityDataSet(int setId)const
{
if (setId >100) {
setId = 0;
}
QList<QVariantHash> retVal;
QVariantHash node;
int visibility = 0;
for (int i =0; i < setId; ++i) {
//valid node
node.clear();
node.insert(ActivityApplicationKeyword, i+120);
node.insert(ActivityActivityKeyword, QString("testactivity%1").arg(i+120));
node.insert(ActivityIconKeyword, QString());
switch (visibility++) {
case 0://visible
node.insert(ActivityVisibleKeyword, true);
break;
case 1://invisible
node.insert(ActivityVisibleKeyword, false);
break;
default://empty
break;
};
if (2 < visibility) {
visibility = 0;
}
retVal.append(node);
}
return retVal;
}
QList<TsTaskChange> T_TsModel::appDataSetFull(int setId)
{
if (setId >100) {
setId = 0;
}
QList<TsTaskChange> retVal;
TsTaskChangeInfo qtChangeItem(-2, -2);
retVal.append(TsTaskChange(qtChangeItem, QSharedPointer<TsTask>()));
for (int iter(0); iter < setId; ++iter) {
//valid node
qtChangeItem = TsTaskChangeInfo(iter, TsTaskChangeInfo::KInvalidOffset);
QSharedPointer<TsTask> node(new TsTask(new TsTaskContent(QString("testapplication%1").arg(iter), iter % 2, iter % 3), *this));
retVal.append(TsTaskChange(qtChangeItem, node));
}
return retVal;
}
QList<TsTaskChange> T_TsModel::changeDataSet5New()
{
QList<TsTaskChange> retVal;
TsTaskChangeInfo qtChangeItem = TsTaskChangeInfo();
// 1 cancel item at start of full update
retVal.append(TsTaskChange(qtChangeItem, QSharedPointer<TsTask>()));
// now 5 new items and changesetitem set to insert
for (int iter(0); iter < 5; iter++) {
qtChangeItem = TsTaskChangeInfo(iter, TsTaskChangeInfo::KInvalidOffset);
QSharedPointer<TsTask> node(new TsTask(new TsTaskContent(QString("test %1").arg(iter+1), true, true), *this));
retVal.append(TsTaskChange(qtChangeItem, node));
}
return retVal;
}
QList<TsTaskChange> T_TsModel::changeDataSetDelete1(int index)
{
QList<TsTaskChange> retVal;
TsTaskChangeInfo qtChangeItem(TsTaskChangeInfo::KInvalidOffset, index);
retVal.append(TsTaskChange(qtChangeItem, QSharedPointer<TsTask>()));
return retVal;
}
QList<TsTaskChange> T_TsModel::changeDataSetInsert1(int index)
{
QList<TsTaskChange> retVal;
TsTaskChangeInfo qtChangeItem(index, TsTaskChangeInfo::KInvalidOffset);
QSharedPointer<TsTask> node(new TsTask(new TsTaskContent(QString("inserted %1").arg(index+1), true, true), *this));
retVal.append(TsTaskChange(qtChangeItem, node));
return retVal;
}
QList<TsTaskChange> T_TsModel::changeDataSetChange1(int index)
{
QList<TsTaskChange> retVal;
TsTaskChangeInfo qtChangeItem(index, index);
QSharedPointer<TsTask> node(new TsTask(new TsTaskContent(QString("changed %1").arg(index+1), true, true), *this));
retVal.append(TsTaskChange(qtChangeItem, node));
return retVal;
}
QList<TsTaskChange> T_TsModel::changeDataSetMove1(int newIndex, int oldIndex)
{
QList<TsTaskChange> retVal;
TsTaskChangeInfo qtChangeItem(newIndex, oldIndex);
retVal.append(TsTaskChange(qtChangeItem, QSharedPointer<TsTask>()));
return retVal;
}
int T_TsModel::activityDataSetsCount()const
{
return dataSetsCount;
}
void T_TsModel::clearModel()
{
QMetaObject::invokeMethod(mAppSrv,
"clearTasks");
QMetaObject::invokeMethod(activityService(),
"clearActivities");
mModel->fullUpdate();
}
QTEST_MAIN(T_TsModel)