logsui/logsengine/tsrc/at_logsengine/src/at_logsengine.cpp
author hgs
Fri, 15 Oct 2010 14:47:48 +0300
changeset 21 2f0af9ba7665
parent 0 4a5361db8937
permissions -rw-r--r--
201041

/*
* 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 "at_logsengine.h"
#include <logsmodel.h>
#include <logsevent.h>
#include <logsfilter.h>
#include <logscustomfilter.h>
#include <apacmdln.h>
#include <apgtask.h>
#include <apgcli.h>
#include <hbicon.h>

#include <QtTest/QtTest>

_LIT( KLogTestEvents, "at_logsengine" );
_LIT( KLogTestClientWriter, "logclienttest.exe" );
_LIT( KLogTestClientClearer, "clearlisttest.exe" );

const int logsTestAllEventsCount = 20;
const int logsTestMissedCallsCount = 10;
const int logsTestOtherThanMissedEventsCount = 10;
const int logsTestContact2EventsCount = 2;
const int logsTestContact3EventsCount = 3;

// Note, events are written from .dat file in order where last event is going to
// be first event at db
const QString logsTestAllEvent1Name = "deeppu";
const LogsEvent::LogsDirection logsTestAllEvent1Dir = LogsEvent::DirIn;

const QString logsTestContact2Event2Name = "Jeppis";
const LogsEvent::LogsDirection logsTestContact2Event2Dir = LogsEvent::DirIn;
const QString logsTestContact2Event1Name = "Jeppa";
const LogsEvent::LogsDirection logsTestContact2Event1Dir = LogsEvent::DirMissed;

const QString logsTestContact3Event3Name = "aeppu";
const LogsEvent::LogsDirection logsTestContact3Event3Dir = LogsEvent::DirOut;
const QString logsTestContact3Event2Name = "beppu";
const LogsEvent::LogsDirection logsTestContact3Event2Dir = LogsEvent::DirIn;
const QString logsTestContact3Event1Name = "deppu";
const LogsEvent::LogsDirection logsTestContact3Event1Dir = LogsEvent::DirOut;

const QString logsTestHomeScreenMissedCallerName = "Jeppa";

Q_DECLARE_METATYPE(LogsEvent *)

#define AT_LOGSENG_VERIFY(m, idx, remote, dir) { \
LogsEvent* event = qVariantValue<LogsEvent*>( m.data( m.index(idx, 0), LogsModel::RoleFullEvent ) ); \
QVERIFY( event && event->remoteParty() == remote && event->direction() == dir ); }

void AT_LogsEngine::initTestCase()
{
    TRAPD( err, clearEventsL() );
    Q_ASSERT( err == KErrNone );
    User::After(2000000);
    TRAP( err, writeEventsL() );
    Q_ASSERT( err == KErrNone );
    User::After(2000000);
    mWaiter = new LogsTestModelObserver;
    mModel = new LogsModel(LogsModel::LogsFullModel, true);
    mModel->refreshData();
    connect( mModel, SIGNAL( dataChanged(const QModelIndex&,const QModelIndex&)), 
           mWaiter, SLOT(somethingCompleted()) );
    connect( mModel, SIGNAL( rowsInserted(const QModelIndex&,int,int)), 
        mWaiter, SLOT(somethingCompleted()) );
    connect( mModel, SIGNAL( rowsRemoved(const QModelIndex&,int,int)), 
        mWaiter, SLOT(somethingCompleted()) );
    connect( mModel, SIGNAL(modelReset()), 
        mWaiter, SLOT(somethingCompleted()) );
    mWaiter->startWaiting(5000);// wait model to be populated from db
}

void AT_LogsEngine::cleanupTestCase()
{
    delete mModel;
    mModel = 0;
    delete mWaiter;
}


void AT_LogsEngine::init()
{
}

void AT_LogsEngine::cleanup()
{

}

void AT_LogsEngine::testAllEvents()
{
    QVERIFY( mModel->rowCount(QModelIndex()) == logsTestAllEventsCount );
    AT_LOGSENG_VERIFY( (*mModel), 0, logsTestAllEvent1Name, logsTestAllEvent1Dir )
}

void AT_LogsEngine::testFilteredEvents()
{
    LogsCustomFilter filter;
    filter.setContactId(2);
    filter.setSourceModel(mModel);
    QVERIFY( filter.rowCount() == logsTestContact2EventsCount );
    AT_LOGSENG_VERIFY( filter, 0, logsTestContact2Event1Name, logsTestContact2Event1Dir )
    AT_LOGSENG_VERIFY( filter, 1, logsTestContact2Event2Name, logsTestContact2Event2Dir )
    
    filter.setContactId(3);
    filter.setSourceModel(0);
    filter.setSourceModel(mModel);
    QVERIFY( filter.rowCount() == logsTestContact3EventsCount );
    AT_LOGSENG_VERIFY( filter, 0, logsTestContact3Event1Name, logsTestContact3Event1Dir )
    AT_LOGSENG_VERIFY( filter, 1, logsTestContact3Event2Name, logsTestContact3Event2Dir )
    AT_LOGSENG_VERIFY( filter, 2, logsTestContact3Event3Name, logsTestContact3Event3Dir )
    
    filter.setContactId(10345624);
    filter.setSourceModel(0);
    filter.setSourceModel(mModel);
    QVERIFY( filter.rowCount() == 0 ); 
}

void AT_LogsEngine::testMarkEventsSeen()
{
    LogsCustomFilter filter;
    filter.setContactId(2);
    filter.setSourceModel(mModel);
    int unseenCount = 0;
    QVERIFY( filter.rowCount() == 2 );
    for ( int i = 0; i < filter.rowCount(); i++ ){
        LogsEvent* event = qVariantValue<LogsEvent*>( 
                filter.data( filter.index(i, 0), LogsModel::RoleFullEvent ) );
        if ( event && !event->isRead() ){
            unseenCount++;
        }
    }
    QVERIFY( unseenCount == 2 );
    QSignalSpy spy( &filter, SIGNAL( markingCompleted(int)));
    QVERIFY( filter.markEventsSeen() );
    connect( &filter, SIGNAL( markingCompleted(int) ), mWaiter, SLOT( somethingCompleted() ) );
    mWaiter->startWaiting(1000);  // wait marking completion
    mModel->compressData(); // Force refresh
    mModel->refreshData();
    mWaiter->startWaiting(2000);  // wait db refresh completion
   
    QVERIFY( spy.count() == 1 );
    int seenCount = 0;
    for ( int i = 0; i < filter.rowCount(); i++ ){
        LogsEvent* event = qVariantValue<LogsEvent*>( 
                filter.data( filter.index(i, 0), LogsModel::RoleFullEvent ) );
        if ( event && event->isRead() ){
            seenCount++;
        }
    }
    QCOMPARE( seenCount, 2 );
    
}

void AT_LogsEngine::testClearEvents()
{
    LogsCustomFilter filter;
    filter.setContactId(2);
    filter.setSourceModel(mModel);
    QVERIFY( filter.rowCount() == 2 );
    int unseenCount = 0;
    QSignalSpy spy( &filter, SIGNAL( clearingCompleted(int)));
    QVERIFY( filter.clearEvents() );
    connect( &filter, SIGNAL( clearingCompleted(int) ), mWaiter, SLOT( somethingCompleted() ) );
    mWaiter->startWaiting(1000); // wait clearing completion
    mModel->compressData(); // Force refresh
    mModel->refreshData();
    mWaiter->startWaiting(2000); // wait db update completion
    QCOMPARE( filter.rowCount(), 0 );
    QCOMPARE( spy.count(), 1 );
}

void AT_LogsEngine::testHomeScreenUsecase()
{
    // Homescreen missed calls notification plugin uses full model with
    // missed calls filter to find out how many sequential events was
    // received from one caller. If number of them is the same as missed call
    // counter, name of the caller is shown at HS.
    
    
    LogsFilter filter(LogsFilter::Missed);
    const int maxNumMissedCalls = 2;
    filter.setMaxSize(maxNumMissedCalls);
    LogsModel optimizedModel(LogsModel::LogsFullModel);   
    connect( &optimizedModel, SIGNAL( dataChanged(const QModelIndex&,const QModelIndex&)), 
             mWaiter, SLOT(somethingCompleted()) );
    connect( &optimizedModel, SIGNAL( rowsInserted(const QModelIndex&,int,int)), 
        mWaiter, SLOT(somethingCompleted()) );
    connect( &optimizedModel, SIGNAL( rowsRemoved(const QModelIndex&,int,int)), 
        mWaiter, SLOT(somethingCompleted()) );
    connect( &optimizedModel, SIGNAL(modelReset()), 
        mWaiter, SLOT(somethingCompleted()) );
    mWaiter->startWaiting(5000);// wait model to be populated from db
    filter.setSourceModel(&optimizedModel);
    
    // Test data has 10 missed calls from Jeppa but readsize has been configured to 2 so
    // reading stops when 2 missed calls has been read
    QCOMPARE( filter.rowCount(), maxNumMissedCalls );
    AT_LOGSENG_VERIFY( filter, 0, logsTestHomeScreenMissedCallerName, LogsEvent::DirMissed )
    AT_LOGSENG_VERIFY( filter, 1, logsTestHomeScreenMissedCallerName, LogsEvent::DirMissed )
    
    // Filter assigned to full model without read size has all those 10 missed calls
    LogsFilter filter2(LogsFilter::Missed);
    filter2.setSourceModel(mModel);
    QVERIFY( filter2.rowCount() == logsTestMissedCallsCount );
    
    // Verify decoration and display data
    QStringList displayData = filter.data( filter.index(0, 0), Qt::DisplayRole ).toStringList();
    QVERIFY( displayData.count() == 2 );
    QVERIFY( displayData.at(0) == logsTestHomeScreenMissedCallerName );
    QVariant decor = filter.data( filter.index(0, 0), Qt::DecorationRole );
    QApplication* app = qobject_cast<QApplication*>( qApp );
    if ( app ){
        HbIcon icon = qVariantValue<HbIcon>( decor.toList().at(0) );
        QVERIFY( !icon.isNull() );
    } else {
        QVERIFY( decor.isNull() );
    }
    
    
    // Cenrep missed calls counter is not tested here
}

void AT_LogsEngine::clearEventsL()
{
    executeL(KLogTestClientClearer, KNullDesC);
}

void AT_LogsEngine::writeEventsL()
{
    TBuf<100> commandLine;
    // Run and write events named at_logsengine in the .dat
    commandLine.Append( KLogTestEvents );
    executeL(KLogTestClientWriter, commandLine);
}

void AT_LogsEngine::executeL(const TDesC& exeName, const TDesC& commandLine)
{
    RProcess process;
    CleanupClosePushL( process );
    User::LeaveIfError( process.Create( exeName, commandLine ) );
    process.Resume();
    CleanupStack::PopAndDestroy( &process );
}


// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
//

LogsTestModelObserver::LogsTestModelObserver() : 
    mWait(0), mTimer(0), mTimerCallBack(asyncTimerExpired, this)
{
    mTimerEntry.Set(mTimerCallBack);
    mWait = new CActiveSchedulerWait;
    mTimer = CDeltaTimer::NewL(CActive::EPriorityStandard);
    
}
LogsTestModelObserver::~LogsTestModelObserver()
{
    if ( mTimer ){
        mTimer->Remove( mTimerEntry );
    }
    delete mTimer;
    if ( mWait && mWait->IsStarted() ){
        mWait->AsyncStop();
    }
    delete mWait;
    
}
void LogsTestModelObserver::startWaiting(int timeoutInMsec)
{
    if ( !mWait->IsStarted() ){
        startTimerForAsync(timeoutInMsec);
        mWait->Start();
    }
}
     
void LogsTestModelObserver::somethingCompleted()
{
    if ( mWait->IsStarted() ){
        mWait->AsyncStop();
    }
}
void LogsTestModelObserver::startTimerForAsync(int msecs)
{
    mTimer->Remove(mTimerEntry);
    TTimeIntervalMicroSeconds32 interval(msecs*1000);
    mTimer->Queue(interval, mTimerEntry);
}

TInt LogsTestModelObserver::asyncTimerExpired(TAny* ptr)
{
    if ( ptr ){
        static_cast<LogsTestModelObserver*>( ptr )->somethingCompleted();
    }
    return 0;
}