// Copyright (c) 1997-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 <e32test.h>
#include <f32file.h>
#include <s32file.h>
#include <cntdb.h>
#include <cntitem.h>
#include <cntfield.h>
#include <cntfldst.h>
#include <bautils.h>
#include <barsc.h>
#include <barsread.h>
#include <cntmodel.rsg>
#include "T_UTILS.H"
#include <hal.h>
#include "CntClient.h"
#pragma warning(disable:4239) // group label warning
CCntTest* CntTest=NULL;
LOCAL_D RTest test(_L("T_GROUPS"));
TInt CCntClient::iObservers = 0;
const TPtrC KDatabaseFileName=_L("C:T_GROUP");
const TPtrC KTestName=_L("Test Name No %d");
const TPtrC KTestAddress=_L("Test Address No %d");
const TPtrC KTestFamilyName=_L("Test Family Name No %d");
const TPtrC KLongLabel = _L("New Long Label");
const TPtrC KGroupLabel = _L("Group Label No%d");
const TPtrC KTestEmail = _L("Test@Email.com No %d");
const TPtrC KTestCountry = _L("Test Country No %d");
const TPtrC KTestCompany = _L("Test Company No %d");
const TInt KLargeSizeRecords=50;
const TInt KFamilySizeRecords=20;
#define KCardGivenName _L("Given Name #%d")
#define KCardFamilyName _L("Family Name #%d")
#define KCardFieldText _L("Card id %d, text field #%d")
#define KCardFieldEditedText _L("UPDATED Card id %d, text field #%d")
//
//
// SUPPORT MODULES
//
//
GLDEF_C void Panic(TInt aPanic)
//
// Panic the thread with CNTMODEL as the category
//
{
User::Panic(_L("T_GROUP"),aPanic);
}
LOCAL_C void SetNameL(CContactItem& aItem,TUid aType,const TDesC& aName)
//
// Set the contents of a text field, creating the field if required
//
{
CContactItemFieldSet& fieldSet=aItem.CardFields();
const TInt pos=fieldSet.Find(aType);
if (pos!=KErrNotFound)
fieldSet[pos].TextStorage()->SetTextL(aName);
else
Panic(KErrGeneral);
}
LOCAL_C void PopulateDatabaseL(TInt aNumberToPopulate, TBool aPhoneNumbers)
//
// Create and populate the database
//
{
TTime before;
before.UniversalTime();
CContactItem* templ = CntTest->Db()->ReadContactL(0);
CleanupStack::PushL(templ);
for (TInt ii=0;ii<aNumberToPopulate;ii++)
{
CContactItem* item=CContactCard::NewLC(templ);
TBuf<16> name;
name.Format(KTestName,ii);
SetNameL(*item,KUidContactFieldGivenName,name);
if (aPhoneNumbers)
{
TBuf<20> number;
switch(ii%3)
{
case 0:
number.Format(_L("0171-%03d %04d"),(ii*9)%1000,((ii+11)*23)%10000);
break;
case 1:
number.Format(_L("%04d:%04d:%04d:%04d"),(ii*123)%10000,(ii*666)%10000,(ii*234)%10000);
break;
case 2:
number.Format(_L("+00%d-%03d %04d"),(ii*123)%100,(ii*13)%1000,((ii+13)*17)%10000);
break;
}
SetNameL(*item,KUidContactFieldPhoneNumber,number);
if (!(ii%2))
{
number.Format(_L("0181-%03d %04d"),(ii*8)%1000,((ii+11)*22)%10000);
SetNameL(*item,KUidContactFieldPhoneNumber,number);
number.Format(_L("01734-%06d"),(ii*123456)%1000000);
SetNameL(*item,KUidContactFieldPhoneNumber,number);
}
}
TBuf<32> address;
address.Format(KTestAddress,ii);
SetNameL(*item,KUidContactFieldAddress,address);
//
TBuf<32> familyName;
familyName.Format(KTestFamilyName,ii);
SetNameL(*item,KUidContactFieldFamilyName,familyName);
//
TBuf<32> email;
email.Format(KTestEmail,ii);
SetNameL(*item,KUidContactFieldEMail,email);
//
TBuf<32> country;
country.Format(KTestCountry,ii);
SetNameL(*item,KUidContactFieldCountry,country);
//
TBuf<32> company;
company.Format(KTestCompany,ii);
SetNameL(*item,KUidContactFieldCompanyName,company);
//
CntTest->Db()->AddNewContactL(*item); //templ
CleanupStack::PopAndDestroy(); // item
//
if (ii%100==0)
{
test.Printf(_L(".")); // Just to show some life
CntTest->Db()->CompactL();
}
}
CleanupStack::PopAndDestroy();
CntTest->Db()->SetDateFormatTextL(_L("%E%D%X%N%Y %1 %2 %3"));
CntTest->Db()->CompactL();
TTime after;
after.UniversalTime();
TTimeIntervalSeconds secondsTaken;
after.SecondsFrom(before,secondsTaken);
test.Printf(_L(" TIME: %d Secs"),secondsTaken.Int());
test.Printf(_L("\n"));
//test.Getch();
}
//
//
// TEST MODULES
//
//
LOCAL_C void CreateBasicContactGroups()
{
test.Next(_L("Create Basic Groups"));
__ASSERT_ALWAYS(CntTest->Db()->GroupCount()==0,Panic(KErrGeneral));
CContactItem* newGroup = CntTest->Db()->CreateContactGroupL(_L("New Group"));
CContactItem* newGroup2 = CntTest->Db()->CreateContactGroupL();
CleanupStack::PushL(newGroup);
CleanupStack::PushL(newGroup2);
CntTest->CloseDatabase();
CntTest->OpenDatabaseL();
test(CntTest->Db()->GroupCount()==2);
CleanupStack::PopAndDestroy(2); // newGroup newGroup2
}
LOCAL_C void CreateGroupFromAClientL(CCntClient& aCntClient)
{
test.Next(_L("Create a basic group"));
CContactItem* tempGroup = aCntClient.Db()->CreateContactGroupL(_L("New Group"));
delete tempGroup ;
CActiveScheduler::Start();
}
LOCAL_C void DeleteBasicContactGroups()
{
test.Next(_L("Delete Basic Groups"));
TInt groupCount = CntTest->Db()->GroupCount();
__ASSERT_ALWAYS(groupCount==2,Panic(KErrGeneral));
CContactIdArray* groupIdList = CntTest->Db()->GetGroupIdListL();
CleanupStack::PushL(groupIdList);
test(groupIdList->Count()==2);
//
for (TInt ii=0; ii< groupIdList->Count();ii++)
CntTest->Db()->DeleteContactL((*groupIdList)[ii]);
test(CntTest->Db()->CountL()==0); //own card
CContactIdArray* newGroupIdList = CntTest->Db()->GetGroupIdListL();
test(newGroupIdList->Count()==0);
delete newGroupIdList;
CleanupStack::PopAndDestroy(); //groupIdList;
}
LOCAL_C void CheckBasicPopulatedGroup()
{
test.Next(_L("Populate Basic Group"));
CntTest->CloseDatabase();
CntTest->DeleteDatabaseL();
CntTest->CreateDatabaseL();
TRAP_IGNORE(PopulateDatabaseL(KFamilySizeRecords,ETrue));
CContactItem* newGroup = CntTest->Db()->CreateContactGroupLC(_L("Family Group"));
TContactItemId groupId = newGroup->Id();
for(TInt ii=2;ii<12;ii++)
{
CntTest->Db()->AddContactToGroupL(ii,groupId);
}
CntTest->CloseDatabase();
CntTest->OpenDatabaseL();
//
CContactItem* familyGroup = CntTest->Db()->ReadContactLC(groupId);
CContactIdArray* memberArray = STATIC_CAST(CContactGroup*,familyGroup)->ItemsContainedLC();
test(memberArray->Count()==10);
//
CContactItem* familyMember = CntTest->Db()->ReadContactLC(2);
CContactIdArray* groups = STATIC_CAST(CContactCard*, familyMember)->GroupsJoinedLC();
test(groups->Count()==1);
TContactItemId memberShip = (*groups)[0];
test(memberShip==groupId);
CleanupStack::PopAndDestroy(5);
// newGroup familyGroup memberArray familyMember groups
}
LOCAL_C void CheckRemoveMember()
{
test.Next(_L("Remove Group Member a check Persist"));
//
CContactItem* familyMember = CntTest->Db()->ReadContactLC(2);
CContactIdArray* groups = STATIC_CAST(CContactCard*, familyMember)->GroupsJoinedLC();
test(groups->Count()>=1);
TContactItemId memberShip = (*groups)[0];
CContactItem* group = CntTest->Db()->ReadContactLC(memberShip);
CContactIdArray* memberArray = STATIC_CAST(CContactGroup*,group)->ItemsContainedLC();
TInt memberCount1 = memberArray->Count();
//
CntTest->Db()->RemoveContactFromGroupL(*familyMember, *group);
CleanupStack::PopAndDestroy(); // group
//
CContactItem* changedGroup = CntTest->Db()->ReadContactLC(memberShip);
CContactIdArray* newMemberArray = STATIC_CAST(CContactGroup*,changedGroup)->ItemsContainedLC();
test(newMemberArray->Count()==memberCount1-1);
CleanupStack::PopAndDestroy(5); // familyMember groups changedGroup newMemberArray memberarray
}
LOCAL_C void CheckRemoveGroup()
{
test.Next(_L("Remove Group check Persist"));
//
CContactIdArray* groupIdList = CntTest->Db()->GetGroupIdListL();
CleanupStack::PushL(groupIdList);
CContactItem* group = CntTest->Db()->ReadContactLC((*groupIdList)[0]);
CContactIdArray* memberArray = STATIC_CAST(CContactGroup*,group)->ItemsContainedLC();
//
CContactItem* member = CntTest->Db()->ReadContactLC((*memberArray)[0]);
CContactIdArray* memberShipArray = STATIC_CAST(CContactCard*, member)->GroupsJoinedLC();
__ASSERT_ALWAYS(memberShipArray->Count()==1,Panic(KErrGeneral));
test((*memberShipArray)[0]==(*groupIdList)[0]);
//
CntTest->Db()->DeleteContactL((*groupIdList)[0]);
//
CContactItem* newMember = CntTest->Db()->ReadContactLC((*memberArray)[0]);
CContactIdArray* newMemberShipArray = STATIC_CAST(CContactCard*, newMember)->GroupsJoinedLC();
test(newMemberShipArray->Count()==0);
//
CleanupStack::PopAndDestroy(7); // groupidList group memberArray member memberShipArray newMember newMemberShipArray
}
LOCAL_C void CheckLargePopulatedGroup()
{
test.Next(_L("Create MANY Contacts"));
CntTest->CloseDatabase();
CntTest->DeleteDatabaseL();
CntTest->CreateDatabaseL();
TRAP_IGNORE(PopulateDatabaseL(KLargeSizeRecords,ETrue));
CContactItem* newGroup = CntTest->Db()->CreateContactGroupL(_L("Large Group"));
CleanupStack::PushL(newGroup);
TContactItemId groupId = newGroup->Id();
test.Next(_L("Add MANY Contacts to a Group"));
TTime before;
before.UniversalTime();
for(TInt ii=1;ii<KLargeSizeRecords+1;ii++)
{
CntTest->Db()->AddContactToGroupL(ii, groupId); //*tempContact,*newGroup);
if (ii%100==0)
test.Printf(_L(".")); // Just to show some life
}
test(TestGroupStateL(CntTest->Db(),1,KLargeSizeRecords));
TTime after;
after.UniversalTime();
TTimeIntervalSeconds secondsTaken;
after.SecondsFrom(before,secondsTaken);
test.Printf(_L(" TIME: %d Secs"),secondsTaken.Int());
test.Printf(_L("\n"));
//test.Getch();
CntTest->CloseDatabase();
CntTest->OpenDatabaseL();
//
CContactItem* familyGroup = CntTest->Db()->ReadContactL(groupId);
CContactIdArray* memberArray = STATIC_CAST(CContactGroup*,familyGroup)->ItemsContainedLC();
test(memberArray->Count()==KLargeSizeRecords);
delete familyGroup;
//
CContactItem* familyMember = CntTest->Db()->ReadContactL(2);
CContactIdArray* groups = STATIC_CAST(CContactCard*, familyMember)->GroupsJoinedLC();
test(groups->Count()==1);
TContactItemId memberShip = (*groups)[0];
test(memberShip==groupId);
delete familyMember;
CleanupStack::PopAndDestroy(3); // newGroup groups memberArray
}
LOCAL_C void DeleteGroupMembersCheckPersist()
{
test.Next(_L("Delete Group Members Check Persist"));
//
TTime before;
before.UniversalTime();
for(TInt ii=1;ii<KLargeSizeRecords+1;ii++)
{
CntTest->Db()->DeleteContactL(ii);
if (ii%100==0)
test.Printf(_L(".")); // Just to show some life
}
TTime after;
after.UniversalTime();
TTimeIntervalSeconds secondsTaken;
after.SecondsFrom(before,secondsTaken);
test.Printf(_L(" TIME: %d Secs"),secondsTaken.Int());
test.Printf(_L("\n"));
//test.Getch();
//
CContactIdArray* groups = CntTest->Db()->GetGroupIdListL();
CleanupStack::PushL(groups);
CContactItem* group = CntTest->Db()->ReadContactL((*groups)[0]);
CContactIdArray* memberArray = STATIC_CAST(CContactGroup*,group)->ItemsContainedLC();
test(memberArray->Count()==0);
delete group;
CleanupStack::PopAndDestroy(2); // groups memberArray
}
LOCAL_C void CreateManyGroups()
{
test.Next(_L("Populate Database"));
CntTest->CloseDatabase();
CntTest->DeleteDatabaseL();
CntTest->CreateDatabaseL();
// add 5 new contacts
TRAP_IGNORE(PopulateDatabaseL(5,ETrue));
//
test.Next(_L("Create MANY Groups"));
TTime before;
before.UniversalTime();
for(TInt ii=0;ii<KLargeSizeRecords;ii++)
{
TBuf<32> label;
label.Format(KGroupLabel,ii);
CContactItem* newGroup = CntTest->Db()->CreateContactGroupL(label);
if (ii%100==0)
test.Printf(_L(".")); // Just to show some life
delete newGroup;
}
TTime after;
after.UniversalTime();
TTimeIntervalSeconds secondsTaken;
after.SecondsFrom(before,secondsTaken);
test.Printf(_L(" TIME: %d Secs"),secondsTaken.Int());
test.Printf(_L("\n"));
//test.Getch();
test(CntTest->Db()->GroupCount()==KLargeSizeRecords);
//
test.Next(_L("Add 5 Contacts to MANY Groups"));
before.UniversalTime();
for(TInt jj=1;jj<6;jj++)
// add cards to all groups
{
CContactItem* contact = CntTest->Db()->ReadContactL(jj);
CleanupStack::PushL(contact);
for(TInt gg=6;gg<KLargeSizeRecords+6;gg++) // assume knowledge of group ids..
{
CntTest->Db()->AddContactToGroupL(jj,gg); //*contact,*group);
if (gg%100==0)
test.Printf(_L(".")); // Just to show some life
}
CleanupStack::PopAndDestroy(); // contact
}
after.UniversalTime();
after.SecondsFrom(before,secondsTaken);
test.Printf(_L(" TIME: %d Secs"),secondsTaken.Int());
test.Printf(_L("\n"));
test(TestGroupStateL(CntTest->Db(),KLargeSizeRecords,5*KLargeSizeRecords));
//test.Getch();
//
test.Next(_L("Check Contacts Group membership"));
before.UniversalTime();
for(TInt gg=1;gg<6;gg++)
// check cards membership
{
CContactItem* contact = CntTest->Db()->ReadContactLC(gg);
CContactIdArray* groups = STATIC_CAST(CContactCard*, contact)->GroupsJoinedLC();
test(groups->Count()==KLargeSizeRecords);
CleanupStack::PopAndDestroy(2); // contact groups
}
after.UniversalTime();
after.SecondsFrom(before,secondsTaken);
test.Printf(_L(" TIME: %d Secs"),secondsTaken.Int());
test.Printf(_L("\n"));
//test.Getch();
}
LOCAL_C void DeleteManyGroups()
{
//
test.Next(_L("Delete MANY Groups"));
TTime before;
before.UniversalTime();
for(TInt ii=6;ii<KLargeSizeRecords+6;ii++)
{
CntTest->Db()->DeleteContactL(ii);
if (ii%100==0)
test.Printf(_L(".")); // Just to show some life
}
TTime after;
after.UniversalTime();
TTimeIntervalSeconds secondsTaken;
after.SecondsFrom(before,secondsTaken);
test.Printf(_L(" TIME: %d Secs"),secondsTaken.Int());
test.Printf(_L("\n"));
//test.Getch();
//
test.Next(_L("Test Card Membership Update"));
test(CntTest->Db()->CountL()==5); // 5 contacts + own card
for(TInt jj=1;jj<6;jj++)
// add cards to all groups
{
CContactItem* contact = CntTest->Db()->ReadContactLC(jj);
CContactIdArray* groups = STATIC_CAST(CContactCard*, contact)->GroupsJoinedLC();
test(groups->Count()==0);
CleanupStack::PopAndDestroy(2); // contact groups
}
CntTest->Db()->CompactL();
}
LOCAL_C void AddCardToCard()
{
//
test.Next(_L("Add Card to Card"));
// assumes Prior Knowldege of contacts 2 & 3 (both are cards)
CntTest->Db()->AddContactToGroupL(2,3);
//
}
LOCAL_C void AddGroupToCard()
{
//
test.Next(_L("Group to Card"));
CContactItem* newGroup = CntTest->Db()->CreateContactGroupL(_L("New Group"));
TContactItemId tempId = newGroup->Id();
delete newGroup;
// assumes Prior Knowldege of contact 3 (is a card)
CntTest->Db()->AddContactToGroupL(tempId,3);
//
}
LOCAL_C void AddBadCardToGroup()
{
//
test.Next(_L("Add unknown Card to group"));
// where id 19 does not exist (assumes knowledge of KLargeSizeRecords+6 as a group)
CntTest->Db()->AddContactToGroupL(KLargeSizeRecords+9,KLargeSizeRecords+6);
//
}
LOCAL_C void AddCardToBadGroup()
{
//
test.Next(_L("Add Card to Unknown group"));
// where id 19 does not exist
CntTest->Db()->AddContactToGroupL(3,KLargeSizeRecords+9);
//
}
LOCAL_C void AddCardToGroupTwice()
{
//
test.Next(_L("Add Card to group Twice"));
// assumes Prior Knowldege of KLargeSizeRecords+6 is a group
CntTest->Db()->AddContactToGroupL(3,KLargeSizeRecords+6);
CntTest->Db()->AddContactToGroupL(3,KLargeSizeRecords+6);
//
}
LOCAL_C void AddFieldToGroup()
{
//
test.Next(_L("Add Field to Group"));
// assumes Prior Knowldege of KLargeSizeRecords+6 is a group
CContactItem* group = CntTest->Db()->OpenContactL(KLargeSizeRecords+6);
CleanupStack::PushL(group);
CContactItemField* field=CContactItemField::NewLC(KStorageTypeText);
field->SetMapping(KUidContactFieldVCardMapUnusedN);
field->TextStorage()->SetTextL(_L("Test Field"));
group->AddFieldL(*field);
//
CntTest->Db()->CommitContactL(*group);
CntTest->CloseDatabase();
CntTest->OpenDatabaseL();
CContactItem* group2 = CntTest->Db()->OpenContactL(KLargeSizeRecords+6);
CContactItemFieldSet& tempFieldSet = group2->CardFields();
test(tempFieldSet.Count()==2);
CntTest->Db()->CloseContactL(KLargeSizeRecords+6);
delete group2;
CleanupStack::Pop(); // field
CleanupStack::PopAndDestroy(); // group
}
LOCAL_C void SetGroupLabel()
{
//
test.Next(_L("Set Group Label"));
// assumes Prior Knowldege of KLargeSizeRecords+6 is a group
CContactIdArray* groupIds = CntTest->Db()->GetGroupIdListL();
CleanupStack::PushL(groupIds);
CContactItem* group = CntTest->Db()->OpenContactL((*groupIds)[0]);
CleanupStack::PushL(group);
TBuf<32> label;
label.Format(KGroupLabel,1);
STATIC_CAST(CContactGroup*,group)->SetGroupLabelL(label);
//
CntTest->Db()->CommitContactL(*group);
CntTest->CloseDatabase();
CntTest->OpenDatabaseL();
CContactItem* group2 = CntTest->Db()->ReadContactLC(KLargeSizeRecords+6,*CntTest->Db()->AllFieldsView());
TPtrC testLabel = STATIC_CAST(CContactGroup*,group2)->GetGroupLabelL();
test(testLabel==label);
//delete group2;
CleanupStack::PopAndDestroy(3); // group groupIds group2
}
LOCAL_C void ChangeGroupLabel()
{
test.Next(_L("Change Group Label"));
// assumes Prior Knowldege of KLargeSizeRecords+6 is a group
CContactIdArray* groupIds = CntTest->Db()->GetGroupIdListL();
CleanupStack::PushL(groupIds);
CContactItem* group = CntTest->Db()->OpenContactL((*groupIds)[0]);
CleanupStack::PushL(group);
TBuf<32> label;
label.Format(KGroupLabel,1);
STATIC_CAST(CContactGroup*,group)->SetGroupLabelL(_L("Glenns Group"));
//
CntTest->Db()->CommitContactL(*group);
CntTest->CloseDatabase();
CntTest->OpenDatabaseL();
CContactItem* group2 = CntTest->Db()->ReadContactLC(KLargeSizeRecords+6,*CntTest->Db()->AllFieldsView());
TPtrC testLabel = STATIC_CAST(CContactGroup*,group2)->GetGroupLabelL();
test(testLabel==_L("Glenns Group"));
//delete group2;
CleanupStack::PopAndDestroy(3); // group groupIds group2
}
// Extended to provide coverage for defect
// EDNBWHE-4HXCXM "group retains link to a nested group after it has been deleted"
//
LOCAL_C void CheckNestedGroup()
{
test.Next(_L("Check Nested Group"));
CntTest->CloseDatabase();
CntTest->DeleteDatabaseL();
CntTest->CreateDatabaseL();
CContactItem* newGroup = CntTest->Db()->CreateContactGroupLC(_L("Family Group"));
TContactItemId groupId = newGroup->Id();
CContactItem* nestedGroup = CntTest->Db()->CreateContactGroupLC(_L("nested Group"));
TContactItemId nestedGroupId = nestedGroup->Id();
CntTest->Db()->AddContactToGroupL(nestedGroupId,groupId);
CntTest->CloseDatabase();
CntTest->OpenDatabaseL();
CContactItem* familyGroup = CntTest->Db()->ReadContactLC(groupId);
CContactIdArray* memberArray = STATIC_CAST(CContactGroup*,familyGroup)->ItemsContainedLC();
test(memberArray->Count()==1);
CContactItem* newNestedGroup = CntTest->Db()->ReadContactLC(nestedGroupId);
CContactIdArray* nestedMemberArray = STATIC_CAST(CContactGroup*,newNestedGroup)->ItemsContainedLC();
test(nestedMemberArray->Count()==0); //fails as count = 0
CContactIdArray* groups = STATIC_CAST(CContactGroup*, newNestedGroup)->GroupsJoinedLC();
test(groups->Count()==1);
TContactItemId memberShip = (*groups)[0];
test(memberShip==groupId);
// If delete a group member, then retrieve the group from the database,
// group.contactCount() is the same and group.getContacts() includes a
// null entry where the deleted group member was.
CntTest->Db()->DeleteContactL(nestedGroupId);
CContactItem* newFamilyGroup = CntTest->Db()->ReadContactLC(groupId);
CContactIdArray* newMemberArray = STATIC_CAST(CContactGroup*,newFamilyGroup )->ItemsContainedLC();
test(newMemberArray->Count()==0); //fails
CleanupStack::PopAndDestroy(9);
// newGroup, nestedGroup, familyGroup memberArray newMemberArray newNestedGroup, newFamilyGroup nestedMemberArray, groups
}
// Helper function for RenameDefectL() below. Sets a sort ordering for the database.
//
LOCAL_C void SetSortOrderL(CContactDatabase& aDb, TFieldType aFieldType)
{
CArrayFix<CContactDatabase::TSortPref>* sortOrder=new(ELeave) CArrayFixFlat<CContactDatabase::TSortPref>(3);
CleanupStack::PushL(sortOrder);
sortOrder->AppendL(CContactDatabase::TSortPref(aFieldType,CContactDatabase::TSortPref::EAsc));
aDb.SortL(sortOrder);
CleanupStack::Pop(); // sortOrder
}
// This tests tries to reproduce defect
// EDNRTRN-4J5C5E "Groups in Cntmodel cannot be renamed.."
//
// This defect was caused because groups weren't included in the view and
// MoveInSortArrayL doesn't check that the contact item will be in the
// iSortedItems list (this list depends on the view chosen).
//
LOCAL_C void RenameDefectL()
{
test.Next(_L("Rename a group"));
CntTest->CloseDatabase();
CntTest->DeleteDatabaseL();
CContactDatabase* db=CntTest->CreateDatabaseL();
_LIT(KCntmodelOriginalName,"Original");
_LIT(KCntmodelRevisedName,"Revised");
CContactItem* newGroup = CntTest->Db()->CreateContactGroupLC(KCntmodelOriginalName);
TContactItemId groupId = newGroup->Id();
CleanupStack::PopAndDestroy(); //newGroup
TContactItemId contactA=AddContactL(db,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,_L("a"));
TContactItemId contactB=AddContactL(db,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,_L("b"));
CntTest->Db()->AddContactToGroupL(contactA,groupId);
CntTest->Db()->AddContactToGroupL(contactB,groupId);
CntTest->Db()->SetDbViewContactType(KUidContactCard);
CntTest->Db()->SortedItemsL(); // ensures theres a iSortedItems
SetSortOrderL(*db,TUid::Uid(KUidContactFieldDefinedTextValue)); // required so that the comparision
CContactGroup* group = static_cast<CContactGroup*>(CntTest->Db()->OpenContactL(groupId));
CleanupStack::PushL(group);
group->SetGroupLabelL(KCntmodelRevisedName);
CntTest->Db()->CommitContactL(*group);
CntTest->Db()->CloseContactL(groupId);
CleanupStack::PopAndDestroy(); //group
CContactItem* revisedGroup = CntTest->Db()->ReadContactLC(groupId,*CntTest->Db()->AllFieldsView());
TPtrC testLabel = static_cast<CContactGroup*>(revisedGroup)->GetGroupLabelL();
test(testLabel==KCntmodelRevisedName);
CleanupStack::PopAndDestroy(); //revisedGroup
}
// This tests reproduces defect
// BET-4YDGB3 "Contacts crashes when creating two entries"
//
// This was caused because the CContactTables::ContactType() method uses the
// iCurrentIdInIdentityTable to determine which contact should be used to read
// the type information from. This member stores the last contact ID to be read
// from the identity table. However, since AddContactToGroupL() doesn't read any
// information from the identity table, the value set in iCurrentIdInIdentityTable
// should be set to KErrNotFound so that the correct contact from main CONTACTS table
// is used.
//
LOCAL_C void QuartzGroupDefectL()
{
test.Next(_L("Quartz defect"));
CntTest->CloseDatabase();
CntTest->DeleteDatabaseL();
CContactDatabase* db=CntTest->CreateDatabaseL();
_LIT(KCntmodelGroupAll,"All");
CContactItem* group = db->CreateContactGroupLC(KCntmodelGroupAll);
TContactItemId groupId = group->Id();
CleanupStack::PopAndDestroy(group);
CntTest->Db()->SetDbViewContactType(KUidContactCard);
CntTest->Db()->SortedItemsL(); // ensures theres a iSortedItems
SetSortOrderL(*db,TUid::Uid(KUidContactFieldDefinedTextValue)); // required so that the comparision
TContactItemId contactB=AddContactL(db,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,_L("B"));
CntTest->Db()->AddContactToGroupL(contactB,groupId);
TContactItemId contactA=AddContactL(db,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,_L("A"));
CntTest->Db()->AddContactToGroupL(contactA,groupId);
}
// Regression testcode for MAT-5B7JD4 "AddContactToGroupL()/RemoveContactFromGroupL() does not update
// object passed as argument"
//
LOCAL_C void GroupAddRemoveTestL()
{
test.Next(_L("Group addition/removal defect"));
CntTest->CloseDatabase();
CntTest->DeleteDatabaseL();
CContactDatabase* db=CntTest->CreateDatabaseL();
_LIT(KCntmodelGroup,"MyGroup");
CContactItem* group = db->CreateContactGroupLC(KCntmodelGroup);
TContactItemId groupId = group->Id();
TContactItemId itemId=AddContactL(db,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,_L("C"));
CContactItem* item = CntTest->Db()->ReadContactLC(itemId);
CntTest->Db()->AddContactToGroupL(*item,*group);
// write change to database
const CContactIdArray* groupsJoined = STATIC_CAST(CContactItemPlusGroup*,item)->GroupsJoined();
test(groupsJoined->Find(groupId)==0);
const CContactIdArray* itemsContained = STATIC_CAST(CContactGroup*,group)->ItemsContained();
test(itemsContained->Find(itemId)==0);
CntTest->Db()->RemoveContactFromGroupL(*item,*group);
test(STATIC_CAST(CContactItemPlusGroup*,item)->GroupsJoined()->Find(groupId)!=0);
test(STATIC_CAST(CContactGroup*,group)->ItemsContained()->Find(itemId)!=0);
CleanupStack::PopAndDestroy(item);
CleanupStack::PopAndDestroy(group);
}
void CompareGroupListL(CCntClient& cntClient1, CCntClient& cntClient2)
{
CContactItem* group1 = NULL;
CContactItem* group2 = NULL;
CContactIdArray* ids1 = cntClient1.Db()->GetGroupIdListL();
CleanupStack::PushL(ids1);
CContactIdArray* ids2 = cntClient2.Db()->GetGroupIdListL();
CleanupStack::PushL(ids2);
TInt groupCount = ids1->Count();
test(cntClient1.Db()->GroupCount()==cntClient1.Db()->GroupCount());
for (TInt i=0;i<groupCount;i++)
{
group1 = cntClient1.Db()->ReadContactLC((*ids1)[groupCount-1]);
group2 = cntClient2.Db()->ReadContactLC((*ids2)[groupCount-1]);
test(group1->LastModified() == group2->LastModified());
test(group1->Id() == group2->Id());
test(group1->Type() == group2->Type());
CleanupStack::PopAndDestroy(2,group1);// group2
}
CleanupStack::PopAndDestroy(2,ids1);//ids2
}
LOCAL_C void TestGroupNotificationsAndGroupIdListUpdateL()
{
test.Next(_L("Test for group addition notification for multifle clients (defect INC018191) "));
// Open DB from cntClient1
CCntClient* cntClient1 = new(ELeave) CCntClient(test,KDatabaseFileName);
CleanupStack::PushL(cntClient1);
cntClient1->CreateDatabaseL();
// Open DB from cntClient2
CCntClient* cntClient2 = new(ELeave) CCntClient(test,KDatabaseFileName);
CleanupStack::PushL(cntClient2);
cntClient2->OpenDatabaseL();
// Check that no group is visible from both clients
CContactIdArray * ids1 = cntClient1->Db()->GetGroupIdListL();
CleanupStack::PushL(ids1);
CContactIdArray * ids2 = cntClient2->Db()->GetGroupIdListL();
CleanupStack::PushL(ids2);
test(ids1->Count()==0);
test(ids2->Count()==0);
CleanupStack::PopAndDestroy(2,ids1);// ids2
ids1=NULL;
ids2=NULL;
// Create a group from the first client
TRAPD(err,CreateGroupFromAClientL(*cntClient1)); //start the Active Scheduler and then stop it in the event handler
test(err==KErrNone);
// Check that the newly added group can be seen by both clients and it is the same object
test(cntClient1->Db()->GroupCount()==1);
test(cntClient2->Db()->GroupCount()==1);
CompareGroupListL(*cntClient1,*cntClient2);
// Create a group from the second client
TRAP(err,CreateGroupFromAClientL(*cntClient2)); //start the Active Scheduler and then stop it in the event handler
test(err==KErrNone);
// Check that now 2 groups can be seen from both clients ..
CompareGroupListL(*cntClient1,*cntClient2);
test(cntClient1->Db()->GroupCount()==2);
test(cntClient2->Db()->GroupCount()==2);
// Now close the database from the two clients and re-open it from a third client
// and chech that there are still 2 groups
cntClient1->CloseDatabase();
cntClient2->CloseDatabase();
CleanupStack::PopAndDestroy(2,cntClient1);// cntClient1, cntClient2
CCntClient* cntClient3 = new(ELeave) CCntClient(test,KDatabaseFileName);
CleanupStack::PushL(cntClient3);
cntClient3->OpenDatabaseL();
test(cntClient3->Db()->GroupCount()==2);
CleanupStack::PopAndDestroy(cntClient3);
cntClient3 = NULL;
}
LOCAL_C void TestReadContactTextDefL() // Added to test changes made for DEF065476 and DEF065477
{
test.Next(_L("Testing ReadContactTextDef ( Defect DEF065476 and DEF065477 )"));
CntTest->CloseDatabase();
CntTest->DeleteDatabaseL();
CContactDatabase* db=CntTest->CreateDatabaseL();
_LIT(KContactGroup,"ContactGroup");
CContactItem* group = db->CreateContactGroupLC(KContactGroup);
TContactItemId groupId = group->Id();
TBuf<128> scratchBuf;
CntTest->Db()->ReadContactTextDefL(groupId, scratchBuf);
test(scratchBuf==KContactGroup);
test.Printf(_L("The Group name is %S\n"), &scratchBuf);
CleanupStack::PopAndDestroy(group);
}
LOCAL_C void AsyncDbOpenFollowedByAddGroupL()
{
test.Next(_L("Async database open & group creating"));
TRequestStatus requestStatus(0);
CContactOpenOperation* op = CContactDatabase::Open(KDatabaseFileName, requestStatus);
// note: op doesn't have to be on CS
User::WaitForRequest(requestStatus);
CContactDatabase* database = op->TakeDatabase();
delete op;
CleanupStack::PushL(database);
CContactItem* tempGroup = database->CreateContactGroupL(_L("New Group"));
delete tempGroup;
CleanupStack::PopAndDestroy(database);
}
//
//
// MAIN DISPATCH MODULE
//
//
/**
@SYMTestCaseID PIM-T-GROUPS-0001
*/
void DoTestsL()
{
// HAL::SetAutoSwitchOffBehavior(ESwitchOffDisabled);
test.Start(_L("@SYMTESTCaseID:PIM-T-GROUPS-0001 Create new database"));
TRAPD(err,CntTest->CreateDatabaseL());
test(err==KErrNone);
CntTest->CloseDatabase();
TRAP(err,CntTest->OpenDatabaseL());
test(err==KErrNone);
TRAP(err,CreateBasicContactGroups());
test(err==KErrNone);
TRAP(err,DeleteBasicContactGroups());
test(err==KErrNone);
TRAP(err,CheckBasicPopulatedGroup());
test(err==KErrNone);
TRAP(err,CheckRemoveMember());
test(err==KErrNone);
TRAP(err,CheckRemoveGroup());
test(err==KErrNone);
TRAP(err,CheckLargePopulatedGroup());
test(err==KErrNone);
TRAP(err,DeleteGroupMembersCheckPersist());
test(err==KErrNone);
TRAP(err,CreateManyGroups());
test(err==KErrNone);
TRAP(err,DeleteManyGroups());
test(err==KErrNone);
// error checking
TRAP(err,AddCardToCard());
test(err==KErrNotSupported);
TRAP(err,AddGroupToCard());
test(err==KErrNotSupported);
TRAP(err,AddBadCardToGroup());
test(err==KErrNotFound);
TRAP(err,AddCardToBadGroup());
test(err==KErrNotFound);
TRAP(err,AddCardToGroupTwice());
test(err==KErrNone);
TRAP(err,AddFieldToGroup());
test(err==KErrNone);
TRAP(err,SetGroupLabel());
test(err==KErrNone);
TRAP(err,ChangeGroupLabel());
test(err==KErrNone);
TRAP(err,CheckNestedGroup());
test(err==KErrNone);
TRAP(err,RenameDefectL());
test(err==KErrNone);
TRAP(err,QuartzGroupDefectL());
test(err==KErrNone);
TRAP(err,GroupAddRemoveTestL());
test(err==KErrNone);
TRAP(err, TestReadContactTextDefL());
test(err==KErrNone);
CntTest->CloseDatabase();
TRAP(err,TestGroupNotificationsAndGroupIdListUpdateL()); //Test case for defect INC018191
test(err==KErrNone);
TRAP(err, AsyncDbOpenFollowedByAddGroupL());
test(err==KErrNone);
test.Next(_L("Delete database"));
TRAP(err,CntTest->DeleteDatabaseL());
test(err==KErrNone);
}
GLDEF_C TInt E32Main()
{
__UHEAP_MARK;
CntTest=new(ELeave) CCntTest;
CntTest->ConstructL(test,KDatabaseFileName);
TRAPD(err,DoTestsL());
CntTest->EndTestLib(err);
__UHEAP_MARKEND;
return KErrNone;
}