// Copyright (c) 2003-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:
// GroupViewPanic Test module
//
//
#include <e32test.h>
#include <cntdef.h>
#include <cntdb.h>
#include <cntitem.h>
#include <cntfield.h>
#include <cntfldst.h>
#include <cntviewbase.h>
#include "CContactViewEventQueue.h"
_LIT(KTestName, "T_GroupViewPanic");
_LIT(KTestDbName, "c:T_GroupViewPanic.cdb");
LOCAL_D RTest test(KTestName);
class CRemoteViewTestResources : public CBase
{
public:
static CRemoteViewTestResources* NewLC();
void ConstructL();
~CRemoteViewTestResources();
void CreateTestGroupsL();
CContactDatabase* iDb;
CContactIdArray* iContacts;
CContactViewEventQueue* iViewEventQueue;
RContactViewSortOrder iViewSortOrder;
CContactRemoteView* iRemoteView;
};
CRemoteViewTestResources* CRemoteViewTestResources::NewLC()
{
CRemoteViewTestResources* self = new(ELeave) CRemoteViewTestResources;
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
void CRemoteViewTestResources::ConstructL()
{
iDb = CContactDatabase::ReplaceL(KTestDbName);
iContacts = CContactIdArray::NewL();
iViewEventQueue = CContactViewEventQueue::NewL();
iViewSortOrder.AppendL(KUidContactFieldTemplateLabel);
const TContactViewPreferences prefs = static_cast<TContactViewPreferences>
(EGroupsOnly |ESingleWhiteSpaceIsEmptyField | EUnSortedAtEnd);
iRemoteView = CContactRemoteView::NewL(*iViewEventQueue, *iDb, iViewSortOrder, prefs);
// Wait for view to get ready
TContactViewEvent event;
TBool eventReady = iViewEventQueue->ListenForEvent(10,event);
__ASSERT_ALWAYS(eventReady,User::Invariant());
ASSERT(event.iEventType == TContactViewEvent::EReady);
}
CRemoteViewTestResources::~CRemoteViewTestResources()
{
if (iRemoteView)
{
iRemoteView->Close(*iViewEventQueue);
delete iViewEventQueue;
}
iViewSortOrder.Close();
delete iContacts;
delete iDb;
TRAP_IGNORE(CContactDatabase::DeleteDatabaseL(KTestDbName));
}
class CTestResources : public CBase
{
public:
static CTestResources* NewLC();
void ConstructL();
void CreateTestContactsL();
void CreateTestGroupsL();
~CTestResources();
CContactDatabase* iDb;
CContactIdArray* iContacts;
CContactViewEventQueue* iViewEventQueue;
RContactViewSortOrder iViewSortOrder;
CContactLocalView* iLocalView;
};
CTestResources* CTestResources::NewLC()
{
CTestResources* self = new(ELeave) CTestResources;
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
void CTestResources::ConstructL()
{
iDb = CContactDatabase::ReplaceL(KTestDbName);
iContacts = CContactIdArray::NewL();
// Create some contacts into the database (don't create any groups)
CreateTestContactsL();
// Close and reopen the DB (this does not help with the bug)
/*
delete iDb;
iDb = NULL;
iDb = CContactDatabase::OpenL(KTestDbName);
*/
iViewEventQueue = CContactViewEventQueue::NewL();
iViewSortOrder.AppendL(KUidContactFieldTemplateLabel);
// Create a groups only contact view
const TContactViewPreferences prefs =
static_cast<TContactViewPreferences>(EGroupsOnly);
iLocalView = CContactLocalView::NewL
(*iViewEventQueue, *iDb, iViewSortOrder, prefs);
#if defined (_DEBUG)
// Wait for view to get ready
TContactViewEvent event;
#endif
ASSERT(iViewEventQueue->ListenForEvent(10,event));
ASSERT(event.iEventType == TContactViewEvent::EReady);
}
LOCAL_C void AddFieldToContactL
(CContactItem& aContact, TFieldType aFieldType, const TDesC& aText)
{
CContactItemField* field = CContactItemField::NewLC(KStorageTypeText, aFieldType);
field->TextStorage()->SetTextL(aText);
aContact.AddFieldL(*field);
CleanupStack::Pop(field);
}
LOCAL_C TContactItemId CreateTestContactL
(CContactDatabase& aDb,
const TDesC& aFamilyName,
const TDesC& aGivenName,
const TDesC& aCompanyName)
{
CContactCard* card = CContactCard::NewLC();
AddFieldToContactL(*card, KUidContactFieldFamilyName, aFamilyName);
AddFieldToContactL(*card, KUidContactFieldGivenName, aGivenName);
AddFieldToContactL(*card, KUidContactFieldCompanyName, aCompanyName);
const TContactItemId id = aDb.AddNewContactL(*card);
CleanupStack::PopAndDestroy(card);
return id;
}
// Creates a few test contacts.
void CTestResources::CreateTestContactsL()
{
TContactItemId id;
id = CreateTestContactL(*iDb, _L("Example1"), _L("test"), _L("Name1"));
iContacts->AddL(id);
id = CreateTestContactL(*iDb, _L("Example2"), _L("test1"), _L("Name2"));
iContacts->AddL(id);
id = CreateTestContactL(*iDb, _L("Example12"), _L("test0"), _L("Name3"));
iContacts->AddL(id);
id = CreateTestContactL(*iDb, _L("Example13"), _L("test3"), _L("Name4"));
iContacts->AddL(id);
}
CTestResources::~CTestResources()
{
if (iLocalView)
{
iLocalView->Close(*iViewEventQueue);
delete iViewEventQueue;
}
iViewSortOrder.Close();
delete iContacts;
delete iDb;
TRAP_IGNORE(CContactDatabase::DeleteDatabaseL(KTestDbName));
}
LOCAL_C void TestDeleteContactsL()
{
// Create test resources
CTestResources* res = CTestResources::NewLC();
// Delete all contacts in the DB
for (TInt i=0; i < res->iContacts->Count(); ++i)
{
res->iDb->DeleteContactL((*res->iContacts)[i]);
}
CleanupStack::PopAndDestroy(res);
}
void CheckEvent(const TContactViewEvent& event,
TContactViewEvent::TEventType expectedEventType,
TInt expectedUnderlyingIndex,
TContactItemId expectedItemId)
{
test(event.iEventType == expectedEventType);
test(event.iInt == expectedUnderlyingIndex);
test(event.iContactId == expectedItemId);
}
void CRemoteViewTestResources::CreateTestGroupsL()
{
test.Next(_L("Test for creating a remote view and validating that queued events are received in the correct order."));
TContactViewEvent event;
// Create A then "unnanmed", then rename "unnamed" to B
test.Next(_L("Test for Create group A, then create group B"));
CContactItem* group1 = iDb->CreateContactGroupLC(_L("A"));
iViewEventQueue->ListenForEvent(2,event);
CheckEvent(event, TContactViewEvent::EItemAdded, 0, group1->Id());
CContactItem* group0 = iDb->CreateContactGroupLC(_L(""));
iViewEventQueue->ListenForEvent(2,event);
CheckEvent(event, TContactViewEvent::EItemAdded, 1, group0->Id());
CContactItem *group00 = iDb->OpenContactL(group0->Id());
static_cast<CContactGroup*> (group00)->SetGroupLabelL(_L("B"));
iDb->CommitContactL(*group00);
// Received 3 events, grp changed, removed and added
iViewEventQueue->ListenForEvent(2,event);
CheckEvent(event, TContactViewEvent::EGroupChanged, 0, group00->Id());
iViewEventQueue->ListenForEvent(2,event);
CheckEvent(event, TContactViewEvent::EItemRemoved, 1, group00->Id());
iViewEventQueue->ListenForEvent(2,event);
CheckEvent(event, TContactViewEvent::EItemAdded, 1, group00->Id());
// Create D then "unnamed", then rename "unnamed" to C
test.Next(_L("Test for Create group D, then create group C"));
CContactItem* group2 = iDb->CreateContactGroupLC(_L("D"));
iViewEventQueue->ListenForEvent(2,event);
CheckEvent(event, TContactViewEvent::EItemAdded, 2, group2->Id());
CContactItem* group3 = iDb->CreateContactGroupLC(_L(""));
iViewEventQueue->ListenForEvent(2,event);
CheckEvent(event, TContactViewEvent::EItemAdded, 3, group3->Id());
CContactItem *group4 = iDb->OpenContactL(group3->Id());
static_cast<CContactGroup*> (group4)->SetGroupLabelL(_L("C"));
iDb->CommitContactL(*group4);
// Received 3 events, grp changed, removed and added
iViewEventQueue->ListenForEvent(2,event);
CheckEvent(event, TContactViewEvent::EGroupChanged, 0, group4->Id());
iViewEventQueue->ListenForEvent(2,event);
CheckEvent(event, TContactViewEvent::EItemRemoved, 3, group4->Id());
iViewEventQueue->ListenForEvent(2,event);
CheckEvent(event, TContactViewEvent::EItemAdded, 2, group4->Id());
// More complex set of add and deletes.
test.Next(_L("Test-Addgroup E, Addgroup F, Addgroup G , RemoveGroup G Addgroup H RenameGroup H as EA"));
CContactItem* group5 = iDb->CreateContactGroupLC(_L("E"));
CContactItem* group6 = iDb->CreateContactGroupLC(_L("F"));
CContactItem* group7 = iDb->CreateContactGroupLC(_L("G"));
iDb->DeleteContactL(group7->Id());
CContactItem* group8 = iDb->CreateContactGroupLC(_L("H"));
CContactItem *group01 = iDb->OpenContactL(group8->Id());
static_cast<CContactGroup*> (group01)->SetGroupLabelL(_L("EA"));
iDb->CommitContactL(*group01);
// Should receive events for operations above, order is not important
iViewEventQueue->ListenForEvent(2,event);
CheckEvent(event, TContactViewEvent::EItemAdded, 4, group5->Id());
iViewEventQueue->ListenForEvent(2,event);
CheckEvent(event, TContactViewEvent::EItemAdded, 5, group6->Id());
iViewEventQueue->ListenForEvent(2,event);
CheckEvent(event, TContactViewEvent::EItemRemoved, 6, group7->Id());
iViewEventQueue->ListenForEvent(2,event);
CheckEvent(event, TContactViewEvent::EGroupChanged, 0, group8->Id());
// Cleanup
delete group01;
delete group00;
delete group4;
CleanupStack::PopAndDestroy(group8);
CleanupStack::PopAndDestroy(group7);
CleanupStack::PopAndDestroy(group6);
CleanupStack::PopAndDestroy(group5);
CleanupStack::PopAndDestroy(group3);
CleanupStack::PopAndDestroy(group2);
CleanupStack::PopAndDestroy(group0);
CleanupStack::PopAndDestroy(group1);
}
/**
@SYMTestCaseID PIM-T-GROUPVIEWPANIC-0001
@SYMTestType UT
@SYMTestPriority Urgent
@SYMDEF INC097928
@SYMTestCaseDesc Check the sequence of events when groups are added, removed or edited
@SYMTestActions
@SYMTestExpectedResults The sequence of events should be proper.
*/
LOCAL_C void TestEventsForGroupCreationL()
{
// Create test resources
CRemoteViewTestResources * pRes = CRemoteViewTestResources::NewLC();
pRes->CreateTestGroupsL();
CleanupStack::PopAndDestroy(pRes);
}
LOCAL_C void DoTestsL()
{
test.Start(_L("@SYMTESTCaseID:PIM-T-GROUPVIEWPANIC-0001 T_GroupViewPanic"));
TestDeleteContactsL();
TestEventsForGroupCreationL();
test.End();
test.Close();
}
GLDEF_C TInt E32Main()
{
// Init
CTrapCleanup* cleanupStack = CTrapCleanup::New();
if (!cleanupStack)
{
return KErrNoMemory;
}
CActiveScheduler* activeScheduler = new CActiveScheduler;
if (!activeScheduler)
{
return KErrNoMemory;
}
CActiveScheduler::Install(activeScheduler);
// Run the tests
__UHEAP_MARK;
TRAPD(err, DoTestsL());
__UHEAP_MARKEND;
// Cleanup
delete activeScheduler;
delete cleanupStack;
return err;
}