tsdevicedialog/tsdevicedialogplugin/tsrc/t_tsmodel/t_tsmodel.cpp
author Jaakko Haukipuro (Nokia-MS/Oulu) <Jaakko.Haukipuro@nokia.com>
Thu, 16 Sep 2010 12:11:40 +0100
changeset 117 c63ee96dbe5f
permissions -rw-r--r--
Missing activityfw and taskswitcher components - fix for Bug 3670

/*
* 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)