phonebookengines_old/contactsmodel/tsrc/T_DBASE2.CPP
changeset 40 b46a585f6909
equal deleted inserted replaced
37:fd64c38c277d 40:b46a585f6909
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <e32test.h>
       
    17 #include "T_UTILS.H"
       
    18 #include "T_DBASE2.H"
       
    19 #include "CContactDbEventQueue.h"
       
    20 
       
    21 GLDEF_D CCntTest* CntTest=NULL;
       
    22 GLDEF_D RTest test(_L("T_DBASE2"));
       
    23 
       
    24 _LIT(KDatabaseFileName,"C:T_DBASE2");
       
    25 
       
    26 #ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
       
    27 _LIT(KPhysicalPathToDatabase, "c:\\private\\10003A73\\T_DBASE2");
       
    28 #else
       
    29 _LIT(KPhysicalPathToDatabase, "c:\\private\\10003A73\\SQLite__T_DBASE2");
       
    30 #endif
       
    31 
       
    32 const TPtrC KTestEmailAddress=_L("testEmail@symbian.com");
       
    33 
       
    34 class CAsyncFinder : public CBase, public MIdleFindObserver
       
    35 	{
       
    36 public:
       
    37 	~CAsyncFinder();
       
    38 	void ConstructL(CContactDatabase *aContactDatabase, const TDesC& aText,const CContactItemFieldDef *aFieldDef);
       
    39 	void ConstructL(CContactDatabase *aContactDatabase, const CDesCArray& aFindWords,const CContactTextDef *aTextDef,const TCallBack &aCallBack);
       
    40 	inline CContactIdArray *TakeContactIds() {return(iFinder->TakeContactIds());};
       
    41 	inline TInt Error() const {return(iFinder->Error());};
       
    42 protected:
       
    43 // from MIdleFindObserver
       
    44 	void IdleFindCallback();
       
    45 private:
       
    46 	CIdleFinder *iFinder;
       
    47 	};
       
    48 
       
    49 GLDEF_C void Panic(TInt aPanic)
       
    50 //
       
    51 // Panic the thread with CNTMODEL as the category
       
    52 //
       
    53 	{
       
    54 	User::Panic(_L("T_DBASE2"),aPanic);
       
    55 	}
       
    56 
       
    57 LOCAL_C void CreateExistingDatabaseTestL()
       
    58 	{
       
    59 	TRAPD(err,CContactDatabase::CreateL(KDatabaseFileName));
       
    60 	test(err==KErrAlreadyExists);
       
    61 	CContactDatabase *db=NULL;
       
    62 	TRAP(err,db=CContactDatabase::OpenL(KDatabaseFileName));
       
    63 	test(err==KErrNone);
       
    64 	delete db;
       
    65 	}
       
    66 
       
    67 	
       
    68 LOCAL_C void SetNameL(CContactItem& aItem,TUid aType,const TDesC& aName, TBool aAddField = EFalse)
       
    69 //
       
    70 // Set the contents of a text field, creating the field if required
       
    71 //
       
    72 	{
       
    73 	CContactItemFieldSet& fieldSet=aItem.CardFields();
       
    74 	const TInt pos=fieldSet.Find(aType);
       
    75 	if (!aAddField && pos!=KErrNotFound)
       
    76 		fieldSet[pos].TextStorage()->SetTextL(aName);
       
    77 	else
       
    78 		{
       
    79 		CContactItemField* field=CContactItemField::NewLC(KStorageTypeText,aType);
       
    80    		field->SetMapping(KUidContactFieldVCardMapUnusedN);
       
    81 		field->TextStorage()->SetTextL(aName);
       
    82 		aItem.AddFieldL(*field);
       
    83 		CleanupStack::Pop(); // field
       
    84 		}
       
    85 	}
       
    86 
       
    87 LOCAL_C TContactItemId AddPhoneContact(const TDesC& aName, const TDesC& aNumber)
       
    88 	{
       
    89 	CContactItem* item = CContactCard::NewLC();
       
    90 	SetNameL(*item, KUidContactFieldGivenName, aName, ETrue);
       
    91 	SetNameL(*item, KUidContactFieldPhoneNumber, aNumber, ETrue);
       
    92 	TContactItemId newId = CntTest->Db()->AddNewContactL(*item);
       
    93 	CleanupStack::PopAndDestroy();	// item
       
    94 	return(newId);
       
    95 	}
       
    96 
       
    97 LOCAL_C TInt PopulateDatabaseForAsyncFindByEmailAddrTest(const TDesC& aEmailAddress)
       
    98 	{
       
    99 	//This function generates a database upon which CContactDatabase::AsyncFindL(...) will fail
       
   100 	//as described in DEF036083, thereby validating the provided fix.
       
   101 	//The database comprises 23 entries distributed across two groups.
       
   102 	//Only one entry contains the email address that will match the search criteria used by
       
   103 	//the AsyncFundByEmailTest(...) function.
       
   104 	//It returns the number of items that have aEmailAddress (which is 1).
       
   105 	CContactIdArray* array = NULL;
       
   106 
       
   107 	for(TInt i = 0; i < 2; i++) 
       
   108 	{
       
   109 		TBuf<16> groupName(_L("group"));
       
   110 		groupName.AppendNum(i+1);
       
   111 
       
   112 		CContactItem* group = CntTest->Db()->CreateContactGroupLC(groupName);
       
   113 		CleanupStack::PopAndDestroy(group);
       
   114 
       
   115 	}
       
   116 	 
       
   117 	array = CntTest->Db()->GetGroupIdListL();
       
   118 	CleanupStack::PushL(array);
       
   119 	
       
   120 	// Get two groups
       
   121 	CContactGroup* group = STATIC_CAST(CContactGroup*, CntTest->Db()->ReadContactLC((*array)[0]));
       
   122 	const TContactItemId groupId1 = group->Id();
       
   123 	CleanupStack::PopAndDestroy(group);
       
   124 	group = NULL;
       
   125 
       
   126 	group = STATIC_CAST(CContactGroup*, CntTest->Db()->ReadContactLC((*array)[1]));
       
   127 	const TContactItemId groupId2 = group->Id();
       
   128 	CleanupStack::PopAndDestroy(group);
       
   129 	CleanupStack::PopAndDestroy(array);
       
   130 
       
   131 	TBuf<128> buffer;
       
   132 	TTime now;
       
   133 	now.UniversalTime();
       
   134 	TInt64 seed=now.Int64();
       
   135 	
       
   136 	for(TInt ii = 1; ii <= 23; ii++) 
       
   137 		{
       
   138 
       
   139 		CContactCard* newContact = CContactCard::NewLC();
       
   140 
       
   141 		// Create random first and last names
       
   142 		TBuf<16> firstName;
       
   143 		TBuf<16> lastName;
       
   144 		
       
   145 		TInt c = (Math::Rand(seed)%26)+'A';
       
   146 		firstName.Append(c);
       
   147 		c = (Math::Rand(seed)%26)+'A';
       
   148 		lastName.Append(c);
       
   149 		TInt jj;
       
   150 		for(jj=1;jj<16;jj++)
       
   151 			{
       
   152 			c=(Math::Rand(seed)%26)+'a';
       
   153 			firstName.Append(c);
       
   154 			if(jj>4 && (Math::Rand(seed)&4)==0)
       
   155 				break;
       
   156 			}
       
   157 		for(jj=1;jj<16;jj++)
       
   158 			{
       
   159 			c=(Math::Rand(seed)%26)+'a';
       
   160 			lastName.Append(c);
       
   161 			if(jj>4 && (Math::Rand(seed)&4)==0)
       
   162 				break;
       
   163 			}
       
   164 		
       
   165 		SetNameL(*newContact,KUidContactFieldGivenName,firstName);
       
   166 		SetNameL(*newContact,KUidContactFieldFamilyName,lastName);
       
   167 
       
   168 		if(Math::Rand(seed)%4)
       
   169 			{
       
   170 			buffer=firstName;
       
   171 			buffer.Append('.');
       
   172 			buffer.Append(lastName);
       
   173 			buffer.Append(_L("@email-address.com"));
       
   174 			SetNameL(*newContact,KUidContactFieldEMail,buffer);
       
   175 			}
       
   176 
       
   177 		if(Math::Rand(seed)%4)
       
   178 			SetNameL(*newContact,KUidContactFieldUrl,_L("http://www.some-web-address.co.uk"));
       
   179 
       
   180 		if(Math::Rand(seed)%4)
       
   181 			SetNameL(*newContact,KUidContactFieldAddress,_L("1 Example Road"));
       
   182 
       
   183 		if(Math::Rand(seed)%4)
       
   184 			SetNameL(*newContact,KUidContactFieldPostcode,_L("ZZ99 EXP"));
       
   185 
       
   186 		if(Math::Rand(seed)%4)
       
   187 			SetNameL(*newContact,KUidContactFieldRegion,_L("Example Town"));
       
   188 
       
   189 		if(Math::Rand(seed)%4)
       
   190 			SetNameL(*newContact,KUidContactFieldLocality,_L("Exampleshire"));
       
   191 
       
   192 		SetNameL(*newContact,KUidContactFieldPhoneNumber,_L("+02079460500"));
       
   193 
       
   194 		if(Math::Rand(seed)%4)
       
   195 			SetNameL(*newContact,KUidContactFieldNote,_L("The quick brown fox jumps over the smelly dog The quick brown dog jumps over the smelly cat"));
       
   196 
       
   197 		if(Math::Rand(seed)%4)
       
   198 			SetNameL(*newContact,KUidContactFieldCompanyName,_L("Symbian Foundation"));
       
   199 
       
   200 		const TContactItemId id = CntTest->Db()->AddNewContactL(*newContact);
       
   201 
       
   202 		CleanupStack::PopAndDestroy(newContact);
       
   203 
       
   204 
       
   205 		if(Math::Rand(seed)%2)
       
   206 			CntTest->Db()->AddContactToGroupL(id, groupId1);
       
   207 		else
       
   208 			CntTest->Db()->AddContactToGroupL(id, groupId2);
       
   209 		}
       
   210 
       
   211 		//Modify the 23rd entry so that it has a specific email address that will
       
   212 		//be the search criteria used in AsyncFindByEmailTest(...).
       
   213 		CContactItem* itemToModify = NULL;
       
   214 		TContactIter iter(*CntTest->Db());
       
   215 		TInt theid;
       
   216 		theid=iter.FirstL();
       
   217 		while(theid!=KNullContactId )
       
   218 		{
       
   219 			if(theid == 23)
       
   220 			{
       
   221 				itemToModify=CntTest->Db()->OpenContactL(theid);
       
   222 				CleanupStack::PushL(itemToModify);
       
   223 				buffer.Zero();
       
   224 				buffer.Append(aEmailAddress);
       
   225 				SetNameL(*itemToModify,KUidContactFieldEMail,buffer);
       
   226 				CntTest->Db()->CommitContactL(*itemToModify);
       
   227 				CleanupStack::PopAndDestroy(itemToModify);
       
   228 
       
   229 			}
       
   230 			theid=iter.NextL();
       
   231 		}
       
   232 		
       
   233 		
       
   234 
       
   235 		return 1;
       
   236 
       
   237 	}
       
   238 
       
   239 LOCAL_C void PopulateDatabaseL(TBool aPhoneNumbers)
       
   240 //
       
   241 // Create and populate the database
       
   242 //
       
   243 	{
       
   244 	for (TInt ii=0;ii<KTotalNumRecords;ii++)
       
   245 		{
       
   246 		CContactItem* item=CContactCard::NewLC();
       
   247 		TBuf<16> name;
       
   248 		name.Format(KTestName,ii);
       
   249    		SetNameL(*item,KUidContactFieldFamilyName,name,ETrue);
       
   250 		if (aPhoneNumbers)
       
   251 			{
       
   252 			TBuf<20> number;
       
   253 			switch(ii%3)
       
   254 				{
       
   255 				case 0:
       
   256 					number.Format(_L("0171-%03d %04d"),(ii*9)%1000,((ii+11)*23)%10000);
       
   257 					break;
       
   258 				case 1:
       
   259 					number.Format(_L("%04d:%04d:%04d:%04d"),(ii*123)%10000,(ii*666)%10000,(ii*234)%10000);
       
   260 					break;
       
   261 				case 2:
       
   262 					number.Format(_L("+00%d-%03d %04d"),(ii*123)%100,(ii*13)%1000,((ii+13)*17)%10000);
       
   263 					break;
       
   264 				}
       
   265    			SetNameL(*item,KUidContactFieldPhoneNumber,number,ETrue);
       
   266 			if (!(ii%2))
       
   267 				{
       
   268 				number.Format(_L("0181-%03d %04d"),(ii*8)%1000,((ii+11)*22)%10000);
       
   269 	   			SetNameL(*item,KUidContactFieldPhoneNumber,number,ETrue);
       
   270 				number.Format(_L("01734-%06d"),(ii*123456)%1000000);
       
   271 	   			SetNameL(*item,KUidContactFieldPhoneNumber,number,ETrue);
       
   272 				}
       
   273 			}
       
   274 		if (ii%2)
       
   275 			{
       
   276 			TBuf<16> address;
       
   277 			address.Format(KTestAddress,ii);
       
   278 			CContactItemField* field=CContactItemField::NewLC(KStorageTypeText,KUidContactFieldAddress);
       
   279 			field->SetMapping(KUidContactFieldVCardMapADR);
       
   280 			field->TextStorage()->SetText(address.AllocL());
       
   281 			item->AddFieldL(*field);
       
   282 			CleanupStack::Pop(); // field
       
   283 			}
       
   284 		if (ii%3)
       
   285 			{
       
   286 			CContactItemField* field=CContactItemField::NewLC(KStorageTypeDateTime,KUidContactFieldBirthday);
       
   287 			field->DateTimeStorage()->SetTime(TDateTime(1990+ii,(TMonth)(ii%12),(ii*3)%28,1,2,3,4));
       
   288 			item->AddFieldL(*field);
       
   289 			CleanupStack::Pop(); // field
       
   290 			}
       
   291 		if (ii%4)
       
   292 			{
       
   293 			CContactItemField* field=CContactItemField::NewLC(KStorageTypeStore);
       
   294     		field->SetMapping(KUidContactFieldVCardMapAGENT);
       
   295 			item->AddFieldL(*field);
       
   296 			CleanupStack::Pop(); // field
       
   297 			}
       
   298 		if (ii%6)
       
   299 			{
       
   300 			CContactItemField* field=CContactItemField::NewLC(KStorageTypeContactItemId);
       
   301 			field->SetMapping(KUidContactFieldVCardMapAGENT);
       
   302 			item->AddFieldL(*field);
       
   303 			CleanupStack::Pop(); // field
       
   304 			}
       
   305 		CntTest->Db()->AddNewContactL(*item);
       
   306 		CleanupStack::PopAndDestroy(); // item
       
   307 		}
       
   308 	CntTest->Db()->SetDateFormatTextL(_L("%E%D%X%N%Y %1 %2 %3"));
       
   309 	}
       
   310 
       
   311 LOCAL_C void CreateBasicContactGroupsL()
       
   312 	{
       
   313 	test.Next(_L("Create Basic Groups"));
       
   314 	__ASSERT_ALWAYS(CntTest->Db()->GroupCount()==0,Panic(KErrGeneral));
       
   315 	CntTest->Db()->CreateContactGroupLC(_L("New Group 1"));
       
   316 	CntTest->Db()->CreateContactGroupLC(_L("New Group 2"));
       
   317 	CntTest->CloseDatabase();
       
   318 	CntTest->OpenDatabaseL();
       
   319 	test(CntTest->Db()->GroupCount()==2);
       
   320 	CleanupStack::PopAndDestroy(2); // newGroup newGroup2
       
   321 	}
       
   322 
       
   323 LOCAL_C void CreateBasicOwnCardL()
       
   324 	{
       
   325 	test.Next(_L("Create Basic Own Card"));
       
   326 	CContactItem* newOwn = CntTest->Db()->CreateOwnCardL();
       
   327 	delete newOwn;
       
   328 	CntTest->CloseDatabase();
       
   329 	CntTest->OpenDatabaseL();
       
   330 	CContactItem* newOwnCard = CntTest->Db()->OpenContactLX(CntTest->Db()->OwnCardId());
       
   331 	CleanupStack::PushL(newOwnCard);
       
   332 	CContactItemField* field=CContactItemField::NewLC(KStorageTypeText,KUidContactFieldFamilyName);
       
   333 	field->SetMapping(KUidContactFieldVCardMapUnusedN);
       
   334 	field->TextStorage()->SetTextL(_L("Dale"));
       
   335 	newOwnCard->AddFieldL(*field);
       
   336 	CntTest->Db()->CommitContactL(*newOwnCard);
       
   337 	CleanupStack::Pop(); // field
       
   338 	CleanupStack::PopAndDestroy(2); // newOwnCard close
       
   339 	}
       
   340 
       
   341 LOCAL_C void NavigateL()
       
   342 	{
       
   343 	test.Next(_L("Navigate from start to end"));
       
   344 	TContactIter iter(*CntTest->Db());
       
   345 	TContactItemId id=iter.FirstL();
       
   346 	TInt count=1;
       
   347 	FOREVER
       
   348 		{
       
   349 		TContactItemId newId=iter.NextL();
       
   350 		if (newId==id || newId==KNullContactId)
       
   351 			break;
       
   352 		++count;
       
   353 		}
       
   354 	test(count==KTotalNumRecords); // +1 for own card
       
   355 
       
   356 	test.Next(_L("Navigate from end to start"));
       
   357 	id=iter.LastL();
       
   358 	count=1;
       
   359 	FOREVER
       
   360 		{
       
   361 		TContactItemId newId=iter.PreviousL();
       
   362 		if (newId==id || newId==KNullContactId)
       
   363 			break;
       
   364 		++count;
       
   365 		}
       
   366 	test(count==KTotalNumRecords); // +1 for own card
       
   367 	}
       
   368 
       
   369 
       
   370 LOCAL_C void CrystalSortRegressionTestL()
       
   371 	{
       
   372 	test.Next(_L("Sort regression test"));
       
   373 	CContactDatabase& db = *CntTest->CreateDatabaseL();
       
   374 	_LIT(KFirstNameCarl,"Carl");
       
   375 	_LIT(KFirstNameChris,"Chris");
       
   376 	TContactItemId one=AddContactL(&db,KUidContactFieldGivenName,KUidContactFieldVCardMapUnusedN,KFirstNameCarl);
       
   377 	TContactItemId two=AddContactL(&db,KUidContactFieldGivenName,KUidContactFieldVCardMapUnusedN,KFirstNameChris);
       
   378 	
       
   379 	CContactIdArray* unsortedArray = CContactIdArray::NewLC();
       
   380 	unsortedArray->AddL(one);
       
   381 	unsortedArray->AddL(two);
       
   382 	CArrayFix<CContactDatabase::TSortPref>* sortOrder = new(ELeave) CArrayFixFlat<CContactDatabase::TSortPref>(1);
       
   383 	CleanupStack::PushL(sortOrder);
       
   384 	CContactDatabase::TSortPref sortPref(KUidContactFieldDefinedText,CContactDatabase::TSortPref::EAsc);
       
   385 	sortOrder->AppendL(sortPref);
       
   386 
       
   387 	CContactIdArray* sorted = db.SortArrayLC(unsortedArray, sortOrder);
       
   388 	test((*sorted)[0]==one);
       
   389 	test((*sorted)[1]==two);
       
   390 	CleanupStack::PopAndDestroy(3, unsortedArray);
       
   391 	CntTest->CloseDatabase();
       
   392 	}
       
   393 
       
   394 LOCAL_C void CheckTemplateRefId()
       
   395 	{
       
   396 	test.Next(_L("Checking TemplateRefId after Commit"));
       
   397 	CContactDatabase *db=CntTest->CreateDatabaseL();
       
   398 	TContactItemId id=AddContactL(db,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,_L("5432"));;
       
   399 	__ASSERT_ALWAYS(id!=KNullContactId,Panic(KErrGeneral));
       
   400 	CContactItem* item = db->OpenContactL(id);
       
   401 	CleanupStack::PushL(item);	
       
   402 	item->SetTemplateRefId(KNullContactId);
       
   403 	db->CommitContactL(*item);
       
   404 	CContactItem* retItem = db->ReadContactL(id);
       
   405 	CleanupStack::PushL(retItem);	
       
   406 	test(retItem->TemplateRefId()==KNullContactId);
       
   407 	db->CloseContactL(id);
       
   408 	CleanupStack::PopAndDestroy(2);
       
   409 	CntTest->CloseDatabase();
       
   410 	}
       
   411 
       
   412 LOCAL_C void TestDeletingRecords()
       
   413 	{
       
   414 	test.Next(_L("Deleting records"));
       
   415 //
       
   416 	CContactDatabase *db=CntTest->CreateDatabaseL();
       
   417 //	CntTest->DeleteAllTemplateFieldsL();
       
   418 //
       
   419 	TContactItemId id1=AddContactL(db,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,_L("3333"));
       
   420 	TContactItemId id2=AddContactL(db,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,_L("2222"));
       
   421 	TContactItemId id3=AddContactL(db,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,_L("1111"));
       
   422 	test(db->CountL()==3);  // +1 own card
       
   423 	CntTest->AdjustContactAccessCountL(id2,1);
       
   424 	db->DeleteContactL(id2);
       
   425 	test(db->CountL()==2); // +1 own card
       
   426 	CntTest->CheckDeletedContact(id2);
       
   427 	CntTest->AdjustContactAccessCountL(id2,-1);
       
   428 	CntTest->CheckContactDoesNotExist(id2);
       
   429 	test(db->CountL()==2); // +1 own card
       
   430 	db->DeleteContactL(id3);
       
   431 	test(db->CountL()==1); // +1 own card
       
   432 	CntTest->AdjustContactAccessCountL(id1,5);
       
   433 	db->DeleteContactL(id1);
       
   434 	test(db->CountL()==0); // +1 own card 
       
   435 	CntTest->CheckDeletedContact(id1);
       
   436 	CntTest->AdjustContactAccessCountL(id1,-4);
       
   437 	CntTest->CheckDeletedContact(id1);
       
   438 	CntTest->AdjustContactAccessCountL(id1,-1);
       
   439 	CntTest->CheckContactDoesNotExist(id1);
       
   440 //
       
   441 	CntTest->CloseDatabase();
       
   442 //
       
   443 	db=CntTest->CreateDatabaseL();
       
   444 	for(TInt loop=0;loop<200;loop++)
       
   445 		{
       
   446 		TBuf<128> text;
       
   447 		text.Format(_L("Delete me %d"),loop);
       
   448 		AddContactL(db,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,text);
       
   449 		}
       
   450 	db->DeleteContactsL(*CContactIdArray::NewLC(db->SortedItemsL()));
       
   451 	CleanupStack::PopAndDestroy();	// Id Array
       
   452 	test(db->SortedItemsL()->Count()==0);
       
   453 	
       
   454 	// Test full deletion of Phone Fields after Contact deletion INC047110
       
   455 	_LIT(KShortNumber, "555");
       
   456 	_LIT(KNameOne, "First");
       
   457 	_LIT(KNameTwo, "Second");
       
   458 	const TInt KNumMatchDigit = 3;
       
   459 	
       
   460 	// Add two Contacts with the same short (<7 digit) number
       
   461 	TContactItemId ident1 = AddPhoneContact(KNameOne, KShortNumber);
       
   462 	TContactItemId ident2 = AddPhoneContact(KNameTwo, KShortNumber);
       
   463 	
       
   464 	// delete one of them
       
   465 	CntTest->Db()->DeleteContactL(ident1);
       
   466 	
       
   467 	CContactIdArray* array = CntTest->Db()->MatchPhoneNumberL(KShortNumber, KNumMatchDigit);
       
   468 	CleanupStack::PushL(array);
       
   469 	
       
   470 	// the phone number related to ident1 should also be deleted
       
   471 	test(array->Count() == 1);
       
   472 	
       
   473 	// tidy up
       
   474 	CleanupStack::PopAndDestroy(array);
       
   475 	CntTest->Db()->DeleteContactL(ident2);
       
   476 	
       
   477 	CntTest->CloseDatabase();
       
   478 	}
       
   479 
       
   480 LOCAL_C void TestLabelValidate(const TDesC &aLabel, TBool aValid, TInt aBadPos)
       
   481 	{
       
   482 	TInt badPos;
       
   483 	TBool isValid=CContactItemField::IsValidLabel(aLabel,badPos);
       
   484 	if (aValid)
       
   485 		test(isValid);
       
   486 	else
       
   487 		{
       
   488 		test(!isValid);
       
   489 		test(aBadPos==badPos);
       
   490 		}
       
   491 	}
       
   492 
       
   493 LOCAL_C void LabelValidating()
       
   494 	{
       
   495 	test.Next(_L("Label validating"));
       
   496 	TestLabelValidate(_L("Good"),ETrue,0);
       
   497 	TestLabelValidate(_L(""),ETrue,0);
       
   498 	TestLabelValidate(_L("Bad.Label"),EFalse,3);
       
   499 	TestLabelValidate(_L("."),EFalse,0);
       
   500 	TestLabelValidate(_L("Bad Bad Bad Bad Bad Bad Bad Bad Bad Bad Bad Bad Bad Bad Bad Bad Bad Bad Bad Bad Bad Bad Bad Bad #Bad Bad Bad Bad Bad Bad Bad Bad "),ETrue,0);
       
   501 	}
       
   502 
       
   503 class CLetChangeNotiferRun : public CTimer
       
   504 	{
       
   505 public:
       
   506 	inline CLetChangeNotiferRun() : CTimer(EPriorityStandard) {};
       
   507 	void ConstructL();
       
   508 	void RunL();
       
   509 	};
       
   510 
       
   511 void CLetChangeNotiferRun::RunL()
       
   512 	{
       
   513 	CActiveScheduler::Stop();
       
   514 	}
       
   515 
       
   516 void CLetChangeNotiferRun::ConstructL()
       
   517 	{
       
   518 	CTimer::ConstructL();
       
   519 	CActiveScheduler::Add(this);
       
   520 	}
       
   521 
       
   522 LOCAL_C void CountL(TBool aCheckAll)
       
   523 	{
       
   524 	CContactDatabase *db=CntTest->CreateDatabaseL();
       
   525 	test.Next(_L("Count()"));
       
   526 	TContactItemId deleteItem=KNullContactId;
       
   527 	TInt loop=0;
       
   528 	for (;loop<10;loop++)
       
   529 		{
       
   530 		if (aCheckAll)
       
   531 			test(db->CountL()==loop); // +1 own card
       
   532 		CContactItem* item=CContactCard::NewLC();
       
   533 		TBuf<16> name;
       
   534 		name.Format(KTestName,loop);
       
   535 		CContactItemField* field=CContactItemField::NewLC(KStorageTypeText,KUidContactFieldFamilyName);
       
   536 		field->SetMapping(KUidContactFieldVCardMapUnusedN);
       
   537 		field->TextStorage()->SetTextL(name);
       
   538 		item->AddFieldL(*field);
       
   539 		CleanupStack::Pop(); // field
       
   540 		TContactItemId itemId=db->AddNewContactL(*item);
       
   541 		if (loop==5)
       
   542 			deleteItem=itemId;
       
   543 		CleanupStack::PopAndDestroy(); // item
       
   544 		}
       
   545 	if (aCheckAll)
       
   546 		test(db->CountL()==loop); // +1 own card
       
   547 //
       
   548 	CContactDatabase* db2=CntTest->OpenDatabaseL();
       
   549 	test(db->CountL()==db2->CountL());
       
   550 //
       
   551 	db->DeleteContactL(deleteItem);
       
   552 //
       
   553 	CLetChangeNotiferRun *letChangeNotiferRun=new(ELeave) CLetChangeNotiferRun;
       
   554 	CleanupStack::PushL(letChangeNotiferRun);
       
   555 	letChangeNotiferRun->ConstructL();
       
   556 	letChangeNotiferRun->After(1000000);
       
   557 	CActiveScheduler::Start();
       
   558 	CleanupStack::PopAndDestroy();	// letChangeNotiferRun
       
   559 	test(db->CountL()==loop-1); //-1 deleted +1 own card
       
   560 	test(db2->CountL()==loop-1); //-1 deleted +1 own card
       
   561 //
       
   562 	CntTest->CloseDatabase();
       
   563 	}
       
   564 
       
   565 LOCAL_C void CurrentItemSupportTest()
       
   566 	{	
       
   567 	test.Next(_L("CurrentItemSupport"));
       
   568 	TInt dbCount = CntTest->Db()->CountL();
       
   569 	test(dbCount>1);
       
   570 	CContactItem* currentItem = CntTest->Db()->ReadContactLC(dbCount/2);
       
   571 	CntTest->Db()->SetCurrentItem(currentItem->Id());
       
   572 	TContactItemId currentItemId = CntTest->Db()->GetCurrentItem();
       
   573 	test(currentItemId == currentItem->Id());
       
   574 	CntTest->CloseDatabase();
       
   575 	CntTest->OpenDatabaseL();
       
   576 	currentItemId = KNullContactId;
       
   577 	currentItemId = CntTest->Db()->GetCurrentItem();
       
   578 	test(currentItemId == currentItem->Id());
       
   579 	CntTest->Db()->DeleteContactL(currentItem->Id());
       
   580 	TContactItemId nullCurrentItemId = CntTest->Db()->GetCurrentItem();
       
   581 	test(nullCurrentItemId==KNullContactId);
       
   582 	CleanupStack::PopAndDestroy(); //currentItem
       
   583 	CntTest->CloseDatabase();
       
   584 	CntTest->OpenDatabaseL();
       
   585 	nullCurrentItemId = CntTest->Db()->GetCurrentItem();
       
   586 	test(nullCurrentItemId==KNullContactId);
       
   587 	}
       
   588 	
       
   589 LOCAL_C void ContactIdArrayL()
       
   590 	{
       
   591 	test.Next(_L("ContactIdArray"));
       
   592 	TContactItemId item1=1;
       
   593 	TContactItemId item2=2;
       
   594 	TContactItemId item3=3;
       
   595 	TContactItemId item4=4;
       
   596 	CContactIdArray* ids=CContactIdArray::NewL();
       
   597 	CleanupStack::PushL(ids);	// ids
       
   598 	test(ids->Count()==0);
       
   599 	ids->AddL(item1);
       
   600 	test(ids->Count()==1);
       
   601 	ids->AddL(item2);
       
   602 	ids->AddL(item3);
       
   603 	test(ids->Count()==3);
       
   604 	test((*ids)[0]==item1);
       
   605 	test((*ids)[1]==item2);
       
   606 	test((*ids)[2]==item3);
       
   607 	ids->Remove(1);
       
   608 	test((*ids)[0]==item1);
       
   609 	test((*ids)[1]==item3);
       
   610 	ids->Reset();
       
   611 	test(ids->Count()==0);
       
   612 	ids->AddL(item3);
       
   613 	test(ids->Count()==1);
       
   614 	delete ids;
       
   615 	CleanupStack::Pop();	// ids
       
   616 //
       
   617 	CContactIdArray::NewLC();
       
   618 	CleanupStack::PopAndDestroy();
       
   619 //
       
   620 	CContactIdArray* ids3=CContactIdArray::NewLC();
       
   621 	ids3->AddL(item3);
       
   622 	ids3->AddL(item2);
       
   623 	ids3->AddL(item1);
       
   624 	test(ids3->Count()==3);
       
   625 	ids3->MoveL(1,0);
       
   626 	test((*ids3)[0]==item2 && (*ids3)[1]==item3 && (*ids3)[2]==item1);
       
   627 	ids3->MoveL(0,2);
       
   628 	test((*ids3)[0]==item3 && (*ids3)[1]==item1 && (*ids3)[2]==item2);
       
   629 	ids3->MoveL(2,0);
       
   630 	test((*ids3)[0]==item2 && (*ids3)[1]==item3 && (*ids3)[2]==item1);
       
   631 	ids3->MoveL(0,1);
       
   632 	test((*ids3)[0]==item3 && (*ids3)[1]==item2 && (*ids3)[2]==item1);
       
   633 	ids3->MoveL(1,2);
       
   634 	test((*ids3)[0]==item3 && (*ids3)[1]==item1 && (*ids3)[2]==item2);
       
   635 	ids3->MoveL(2,1);
       
   636 	test((*ids3)[0]==item3 && (*ids3)[1]==item2 && (*ids3)[2]==item1);
       
   637 	ids3->InsertL(1,item4);
       
   638 	test(ids3->Count()==4);
       
   639 	test((*ids3)[0]==item3 && (*ids3)[1]==item4 && (*ids3)[2]==item2 && (*ids3)[3]==item1);
       
   640 //
       
   641 	test(ids3->Find(1)==3);
       
   642 	test(ids3->Find(2)==2);
       
   643 	test(ids3->Find(3)==0);
       
   644 	test(ids3->Find(4)==1);
       
   645 //
       
   646 	CContactIdArray::NewLC(ids3);
       
   647 	CleanupStack::PopAndDestroy();	// New CContactIdArray
       
   648 //
       
   649 	CContactIdArray* ids4=CContactIdArray::NewL(ids3);
       
   650 	CleanupStack::PushL(ids4);
       
   651 	test(ids3->Count()==ids4->Count());
       
   652 	TInt loop=0;
       
   653 	for(;loop<ids4->Count();loop++)
       
   654 		test((*ids3)[loop]==(*ids4)[loop]);
       
   655 //
       
   656 	CleanupStack::PopAndDestroy(2);	// ids4, ids3
       
   657 //
       
   658 	CStreamStore* store=CBufStore::NewLC(3);
       
   659 	RStoreWriteStream tempwrite;
       
   660 	TStreamId streamId=tempwrite.CreateLC(*store);
       
   661 //
       
   662 	ids=CContactIdArray::NewLC();
       
   663 	for(loop=0;loop<100;loop++)
       
   664 		ids->AddL(loop*3);
       
   665 	tempwrite<<*ids;
       
   666 	tempwrite.Close();
       
   667 	store->CommitL();
       
   668 	CleanupStack::PopAndDestroy(2);	// ids, stream
       
   669 //
       
   670 	RStoreReadStream tempread;
       
   671 	tempread.OpenLC(*store,streamId);
       
   672 //
       
   673 	CContactIdArray *ids2=CContactIdArray::NewLC();
       
   674 	tempread>>*ids2;
       
   675 	for(loop=0;loop<100;loop++)
       
   676 		test((*ids2)[loop]==loop*3);
       
   677 	CleanupStack::PopAndDestroy(3);	// ids2,tempread,store
       
   678 	}
       
   679 
       
   680 LOCAL_C void ScanForChangesL()
       
   681 	{
       
   682 	test.Next(_L("Scan for changes"));
       
   683 	CContactDatabase* db=CntTest->OpenDatabaseL();
       
   684 	TTime before;
       
   685 	before.UniversalTime();
       
   686 	User::After(1000000);
       
   687 	CContactItem* item=db->ReadContactLC(2); // assumes id 3 is valid
       
   688 	User::After(1000000);
       
   689 	const TInt KNumImports1=3;
       
   690 	TInt ii=0;
       
   691 	for (;ii<KNumImports1;ii++)
       
   692 		{
       
   693 		CContactCard* card=CContactCard::NewLC(item);
       
   694 		db->AddNewContactL(*card);
       
   695 		CleanupStack::PopAndDestroy(); // card
       
   696 		}
       
   697 	User::After(1000000);
       
   698 	TTime during;
       
   699 	during.UniversalTime();
       
   700 	test(during>before);
       
   701 	User::After(1000000);
       
   702 	const TInt KNumImports2=5;
       
   703 	for (ii=0;ii<KNumImports2;ii++)
       
   704 		{
       
   705 		CContactCard* card=CContactCard::NewLC(item);
       
   706 		db->AddNewContactL(*card);
       
   707 		CleanupStack::PopAndDestroy(); // card
       
   708 		}
       
   709 	User::After(1000000);
       
   710 	TTime after;
       
   711 	after.UniversalTime();
       
   712 	test(after>during);
       
   713 	CContactIdArray* ids=db->ContactsChangedSinceL(before);
       
   714 	test(ids->Count()==KNumImports1+KNumImports2); // +1 template access count
       
   715 	delete ids;
       
   716 	ids=db->ContactsChangedSinceL(during);
       
   717 	test(ids->Count()==KNumImports2); // +1 template access count
       
   718 	delete ids;
       
   719 	ids=db->ContactsChangedSinceL(after);
       
   720 	test(ids->Count()==0);
       
   721 	delete ids;
       
   722 	CntTest->CloseDatabase();
       
   723 	
       
   724 	
       
   725 	test.Next(_L("INC 66340 ContactsChangedSinceL incorrectly uses the TTime argument "));
       
   726 	// Note that the defect fix for INC 66340 relies on the fix for 
       
   727 	// DEF067226: TTime.Parse does not parse microseconds.
       
   728 	// The problem was that ContactsChangedSinceL(t) was incorrectly rounding down 
       
   729 	// the time to the next lowest second. 
       
   730 	// Thus both the times used in the following test 
       
   731 	// were rounded down to the SAME time. The time should not be
       
   732 	// rounded. Only ONE conact has been addded since TTime t2.
       
   733 	// Note there was TWO reasons for this defect:
       
   734 	// (1) The SQL query string used only stipulated the time to the lowest second
       
   735 	// (2) Ttime::Parse did not parse microseconds (i.e. ignored microseconds).
       
   736 	
       
   737 	
       
   738 	db=CntTest->OpenDatabaseL();
       
   739 	
       
   740 	{
       
   741 	TTime t1;
       
   742 	t1.UniversalTime();
       
   743 	CContactCard* card=CContactCard::NewLC(item);
       
   744 	db->AddNewContactL(*card);
       
   745 	CleanupStack::PopAndDestroy(); 
       
   746 	ids=db->ContactsChangedSinceL(t1);
       
   747 	TInt c1 = ids->Count();
       
   748 	test(c1==1); 
       
   749 	delete ids;
       
   750 
       
   751 	User::After(10); //ensure next time stamp is NOT same as previous 
       
   752 	TTime t2;
       
   753 	t2.UniversalTime();
       
   754 	card=CContactCard::NewLC(item);
       
   755 	db->AddNewContactL(*card);
       
   756 	CleanupStack::PopAndDestroy(); 
       
   757 	ids=db->ContactsChangedSinceL(t2);
       
   758 	TInt c2 = ids->Count();
       
   759 	test(c2==1); 
       
   760 	delete ids;
       
   761 	}
       
   762 	
       
   763 	// but, of course, the above test could pass if TTime wraps around into 
       
   764 	// the next second. So, assuming this test is all going to occur within
       
   765 	//  ONE second, we merely have repeat again to accommodate this.
       
   766 	{
       
   767 	User::After(10); //ensure next time stamp is NOT same as previous 
       
   768 	TTime t3;
       
   769 	t3.UniversalTime();
       
   770 	CContactCard* card=CContactCard::NewLC(item);
       
   771 	db->AddNewContactL(*card);
       
   772 	CleanupStack::PopAndDestroy(); 
       
   773 	ids=db->ContactsChangedSinceL(t3);
       
   774 	TInt c3 = ids->Count();
       
   775 	test(c3==1); 
       
   776 	delete ids;
       
   777 
       
   778 	User::After(10); //ensure next time stamp is NOT same as previous
       
   779 	TTime t4;
       
   780 	t4.UniversalTime();
       
   781 	card=CContactCard::NewLC(item);
       
   782 	db->AddNewContactL(*card);
       
   783 	CleanupStack::PopAndDestroy(); 
       
   784 	ids=db->ContactsChangedSinceL(t4);
       
   785 	TInt c4 = ids->Count();
       
   786 	test(c4==1); 
       
   787 	delete ids;
       
   788 	}
       
   789 	CleanupStack::PopAndDestroy(); // item
       
   790 	
       
   791 	CntTest->CloseDatabase();
       
   792 	
       
   793 
       
   794 	
       
   795 	}
       
   796 
       
   797 void ChangePhoneNumber(TContactItemId aId, const TDesC &aNumber)
       
   798 	{
       
   799 	CContactItem* item=CntTest->Db()->OpenContactLX(aId);
       
   800 	CleanupStack::PushL(item);
       
   801 	SetNameL(*item,KUidContactFieldPhoneNumber,aNumber,EFalse);
       
   802 	CntTest->Db()->CommitContactL(*item);
       
   803 	CleanupStack::PopAndDestroy();	// item
       
   804 	CleanupStack::Pop();	// close record
       
   805 	}
       
   806 
       
   807 
       
   808 LOCAL_C TInt FileSizeL()
       
   809 	{
       
   810 	TEntry entry;
       
   811 	User::LeaveIfError(CntTest->Fs().Entry(KPhysicalPathToDatabase, entry));
       
   812 	return(entry.iSize);
       
   813 	}
       
   814 
       
   815 LOCAL_C void TestFileSizeL()
       
   816 	{
       
   817 	const TInt KMaxAddContacts=10;
       
   818 
       
   819 	test.Next(_L("Test File Size"));
       
   820 	CContactDatabase *db=CntTest->CreateDatabaseL();
       
   821 //
       
   822 	TContactItemId id0=AddPhoneContact(_L("x1"), _L("123"));
       
   823 	db->CompactL();
       
   824 	TContactItemId ids[KMaxAddContacts];
       
   825 	for(TInt loop1=1;loop1<KMaxAddContacts;loop1++)
       
   826 		{
       
   827 		TInt size1=FileSizeL();
       
   828 		TInt loop2=0;
       
   829 		for(;loop2<loop1;loop2++)
       
   830 			ids[loop2]=AddPhoneContact(_L("x2"), _L("234"));
       
   831 		for(loop2=0;loop2<loop1;loop2++)
       
   832 			db->DeleteContactL(ids[loop2]);
       
   833 		test(db->FileSize()-db->WastedSpaceInBytes()>0);
       
   834 		
       
   835 		db->CompactL();
       
   836 		TInt size2=FileSizeL();
       
   837 		if (size1!=size2)
       
   838 			db->CountL();
       
   839 		test(size2==db->FileSize());
       
   840 		}
       
   841 //
       
   842 	db->DeleteContactL(id0);
       
   843 	CntTest->CloseDatabase();
       
   844 	}
       
   845 
       
   846 LOCAL_C void DisplayModelVersionNumber()
       
   847 	{
       
   848 	TVersion version=CntTest->Db()->Version();
       
   849 	TBuf<64> buf;
       
   850 	buf.Format(_L("Model version %03d.%03d (%d)\n"),version.iMajor,version.iMinor,version.iBuild);
       
   851 	test.Printf(buf);
       
   852 	}
       
   853 
       
   854 LOCAL_C void SortByTypeTest()
       
   855 	{
       
   856 	// test sort by type
       
   857 	CntTest->CloseDatabase();
       
   858 	CntTest->DeleteDatabaseL();
       
   859 	CntTest->CreateDatabaseL();
       
   860 
       
   861 //create groups
       
   862 	CntTest->Db()->CreateContactGroupLC(_L("New Group 1"));
       
   863 	CntTest->Db()->CreateContactGroupLC(_L("New Group 2"));
       
   864 // create owncard
       
   865 	CntTest->Db()->CreateOwnCardLC();
       
   866 // create multiple templates
       
   867 	_LIT(KTestLabel ,"Test label");
       
   868 	CntTest->Db()->CreateContactCardTemplateLC(KTestLabel,EFalse);
       
   869 	CntTest->Db()->CreateContactCardTemplateLC(KTestLabel,EFalse);
       
   870 	CntTest->Db()->CreateContactCardTemplateLC(KTestLabel,EFalse);
       
   871 	
       
   872 //	do the sort and count
       
   873 	CArrayFix<CContactDatabase::TSortPref>* sortOrder=new(ELeave) CArrayFixFlat<CContactDatabase::TSortPref>(3);
       
   874 	sortOrder->AppendL(CContactDatabase::TSortPref(KUidContactFieldFamilyName,CContactDatabase::TSortPref::EAsc));
       
   875 //
       
   876 	CntTest->Db()->SetDbViewContactType(KUidContactItem);
       
   877 	CntTest->Db()->SortByTypeL(sortOrder); // takes ownership of sortorder
       
   878 	const CContactIdArray *itemIds=CntTest->Db()->SortedItemsL();
       
   879 	test(itemIds->Count()==6);
       
   880 //
       
   881 	sortOrder=new(ELeave) CArrayFixFlat<CContactDatabase::TSortPref>(3);
       
   882 	sortOrder->AppendL(CContactDatabase::TSortPref(KUidContactFieldFamilyName,CContactDatabase::TSortPref::EAsc));
       
   883 	CntTest->Db()->SetDbViewContactType(KUidContactGroup);
       
   884 	CntTest->Db()->SortByTypeL(sortOrder); // takes ownership of sortOrder
       
   885 	const CContactIdArray *groupIds=CntTest->Db()->SortedItemsL();
       
   886 	test(groupIds->Count()==2);
       
   887 //
       
   888 	sortOrder=new(ELeave) CArrayFixFlat<CContactDatabase::TSortPref>(3);
       
   889 	sortOrder->AppendL(CContactDatabase::TSortPref(KUidContactFieldFamilyName,CContactDatabase::TSortPref::EAsc));
       
   890 	CntTest->Db()->SetDbViewContactType(KUidContactOwnCard);
       
   891 	CntTest->Db()->SortByTypeL(sortOrder); // takes ownership of sortOrder
       
   892 	const CContactIdArray *ownCardIds=CntTest->Db()->SortedItemsL();
       
   893 	test(ownCardIds->Count()==1);
       
   894 //
       
   895 	sortOrder=new(ELeave) CArrayFixFlat<CContactDatabase::TSortPref>(3);
       
   896 	sortOrder->AppendL(CContactDatabase::TSortPref(KUidContactFieldFamilyName,CContactDatabase::TSortPref::EAsc));
       
   897 	CntTest->Db()->SetDbViewContactType(KUidContactCard);
       
   898 	CntTest->Db()->SortByTypeL(sortOrder);  // takes ownership of SortOrder
       
   899 	const CContactIdArray *cardIds=CntTest->Db()->SortedItemsL();
       
   900 	test(cardIds->Count()==1);
       
   901 //
       
   902 	sortOrder=new(ELeave) CArrayFixFlat<CContactDatabase::TSortPref>(3);
       
   903 	sortOrder->AppendL(CContactDatabase::TSortPref(KUidContactFieldFamilyName,CContactDatabase::TSortPref::EAsc));
       
   904 	CntTest->Db()->SetDbViewContactType(KUidContactCardTemplate);
       
   905 	CntTest->Db()->SortByTypeL(sortOrder); // takes ownership of sortOrder
       
   906 	const CContactIdArray *templateIds=CntTest->Db()->SortedItemsL();
       
   907 	test(templateIds->Count()==3);
       
   908 //
       
   909 	CleanupStack::PopAndDestroy(6); // newGroup1&2 ownCard1 multiTemplate1,2&3
       
   910 	}
       
   911 
       
   912 LOCAL_C void DeleteManyContacts()
       
   913 	{
       
   914 	test.Next(_L("Test DeleteContacts()"));
       
   915 	CntTest->CloseDatabase();
       
   916 	CntTest->DeleteDatabaseL();
       
   917 	CntTest->CreateDatabaseL();
       
   918 	PopulateDatabaseL(EFalse);
       
   919 
       
   920 	CContactIdArray* contactIds=CContactIdArray::NewLC();
       
   921 	for(TInt i=1;i<KTotalNumRecords;i++)
       
   922 		{
       
   923 		contactIds->AddL(i);
       
   924 		}
       
   925 	test(contactIds->Count()==KTotalNumRecords-1);
       
   926 	CntTest->Db()->DeleteContactsL(*contactIds);
       
   927 	CleanupStack::PopAndDestroy(); // contactIds
       
   928 	}
       
   929 
       
   930 
       
   931 LOCAL_C void TestFileUidL()
       
   932     {
       
   933 	CntTest->CreateDatabaseL();
       
   934 	TBuf<40> fileUid1;
       
   935 	fileUid1=CntTest->Db()->FileUid();
       
   936 	CntTest->CloseDatabase();
       
   937 	User::After(50000);	// as UID is time generated make sure time is different
       
   938 	CntTest->OpenDatabaseL();
       
   939 	test(fileUid1==CntTest->Db()->FileUid());
       
   940 	CntTest->CloseDatabase();
       
   941 	CntTest->CreateDatabaseL();
       
   942 	test(fileUid1!=CntTest->Db()->FileUid());	// Should be different in a new DB
       
   943 	CntTest->CloseDatabase();
       
   944 	}
       
   945 
       
   946 /** 
       
   947  * Regression test for EXT-53JGEN "CContactDatabase::GroupCount() 
       
   948  * crashes when called to a brand new default database"
       
   949  */
       
   950 LOCAL_C void GroupCountRegressionTestL()
       
   951 	{
       
   952 	CntTest->CloseDatabase();
       
   953 	CntTest->DeleteDatabaseL();
       
   954 	CntTest->CreateDatabaseL();
       
   955 	CntTest->Db()->GroupCount();
       
   956 	}
       
   957 
       
   958 /** Check that FindLC() doesn't find aSearchString in the database */
       
   959 LOCAL_C void CheckNoMatchesL(TFieldType aFieldType, const TDesC& aSearchString)
       
   960 	{
       
   961 	CContactItemFieldDef* fieldDef=new(ELeave) CContactItemFieldDef;
       
   962 	CleanupStack::PushL(fieldDef);
       
   963 	fieldDef->AppendL(aFieldType);
       
   964 	CContactIdArray* ids=CntTest->Db()->FindLC(aSearchString,fieldDef);
       
   965 	test(ids->Count()==0);
       
   966 	CleanupStack::PopAndDestroy(2, fieldDef);
       
   967 	}	
       
   968 
       
   969 /** 
       
   970  * Regression test to ensure that contact data is really deleted.
       
   971  * Phone number fields are tested by T_NOMACH
       
   972  */
       
   973 LOCAL_C void DeleteContactDataRegressionTestL()
       
   974 	{
       
   975 	test.Next(_L("Test contact data isn't found for deleted items"));
       
   976 	CntTest->CloseDatabase();
       
   977 	CntTest->DeleteDatabaseL();
       
   978 	CntTest->CreateDatabaseL();
       
   979 	_LIT(KIdentity,"Identity");
       
   980 	_LIT(KContacts,"Contacts");
       
   981 	_LIT(KEmail,"email.address@symbian.com");
       
   982 	CContactItem* item=CContactCard::NewLC();
       
   983 	SetNameL(*item,KUidContactFieldGivenName,KUidContactFieldVCardMapUnusedN,KIdentity,ETrue);
       
   984 	SetNameL(*item,KUidContactFieldAddress,KUidContactFieldVCardMapADR,KContacts, ETrue);
       
   985 	SetNameL(*item,KUidContactFieldEMail,KUidContactFieldVCardMapEMAILINTERNET,KEmail,ETrue);
       
   986 	SetNameL(*item,KUidContactFieldEMail,KUidContactFieldVCardMapEMAILINTERNET,KEmail,ETrue);
       
   987 	item->SetTemplateRefId(KGoldenTemplateId);
       
   988 	TContactItemId id=CntTest->Db()->AddNewContactL(*item);
       
   989 	CleanupStack::PopAndDestroy(item); 
       
   990 	CntTest->Db()->DeleteContactL(id);
       
   991 	CheckNoMatchesL(KUidContactFieldGivenName,KIdentity);
       
   992 	CheckNoMatchesL(KUidContactFieldAddress,KContacts);
       
   993 	CheckNoMatchesL(KUidContactFieldEMail,KEmail);
       
   994 	CntTest->CloseDatabase();
       
   995 	}
       
   996 
       
   997 LOCAL_C void FindContactWithApostropheL()
       
   998 	{
       
   999 	test.Next(_L("Test that you can find contacts with an apostrophe in their name"));
       
  1000 	
       
  1001 	CntTest->CloseDatabase();
       
  1002 	CntTest->DeleteDatabaseL();
       
  1003 	CntTest->CreateDatabaseL();
       
  1004 	
       
  1005 	_LIT(KSearchName1, "diner's");	//word with single apostrophe
       
  1006 	_LIT(KSearchName2, "diner's'");	//word ending with apostrophe
       
  1007 	_LIT(KSearchName3, "'");		//single apostrophe
       
  1008 	_LIT(KSearchName4, "dime''s");	//word with double apostrophe
       
  1009 	_LIT(KSearchName5, "test's test's test"); //exercise both realloc's  
       
  1010 
       
  1011 	_LIT(KIdentity1,"diner's");
       
  1012 	_LIT(KIdentity2,"diner's'");
       
  1013 	_LIT(KIdentity3,"'");
       
  1014 	_LIT(KIdentity4,"dime''s'");
       
  1015 	_LIT(KContacts,"Contacts");
       
  1016 	_LIT(KEmail,"email.address@symbian.com");
       
  1017 
       
  1018 	//create items
       
  1019 	CContactItem* item=CContactCard::NewLC();
       
  1020 	SetNameL(*item,KUidContactFieldGivenName,KUidContactFieldVCardMapUnusedN,KIdentity1,ETrue);
       
  1021 	SetNameL(*item,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,KIdentity2,ETrue);
       
  1022 	SetNameL(*item,KUidContactFieldAdditionalName,KUidContactFieldVCardMapUnusedN,KIdentity3,ETrue);
       
  1023 	SetNameL(*item,KUidContactFieldCompanyName,KUidContactFieldVCardMapUnusedN,KIdentity4,ETrue);
       
  1024 	SetNameL(*item,KUidContactFieldAddress,KUidContactFieldVCardMapADR,KContacts, ETrue);
       
  1025 	SetNameL(*item,KUidContactFieldEMail,KUidContactFieldVCardMapEMAILINTERNET,KEmail,ETrue);
       
  1026 	SetNameL(*item,KUidContactFieldEMail,KUidContactFieldVCardMapEMAILINTERNET,KEmail,ETrue);
       
  1027 	SetNameL(*item,KUidContactFieldEMail,KUidContactFieldVCardMapEMAILINTERNET,KSearchName5,ETrue);
       
  1028 	
       
  1029 	item->SetTemplateRefId(KGoldenTemplateId);
       
  1030 	CntTest->Db()->AddNewContactL(*item);
       
  1031 	CleanupStack::PopAndDestroy(item); 
       
  1032 
       
  1033     //create definition
       
  1034 	CContactItemFieldDef* fieldDef=new(ELeave) CContactItemFieldDef;
       
  1035 	CleanupStack::PushL(fieldDef);
       
  1036 	fieldDef->AppendL(KUidContactFieldGivenName);
       
  1037 	fieldDef->AppendL(KUidContactFieldFamilyName);
       
  1038 	fieldDef->AppendL(KUidContactFieldAdditionalName);
       
  1039 	fieldDef->AppendL(KUidContactFieldCompanyName);
       
  1040 	
       
  1041     //search for contact1
       
  1042 	CContactIdArray* result = CntTest->Db()->FindLC(KSearchName1, fieldDef);
       
  1043 	test(result->Count()==1);
       
  1044 
       
  1045 	//search for contact2
       
  1046 	CContactIdArray* result2 = CntTest->Db()->FindLC(KSearchName2, fieldDef);
       
  1047 	test(result2->Count()==1);
       
  1048 	
       
  1049 	//search for contact3
       
  1050 	CContactIdArray* result3 = CntTest->Db()->FindLC(KSearchName3, fieldDef);
       
  1051 	test(result3->Count()==1);
       
  1052 	
       
  1053 	//search for contact4
       
  1054 	CContactIdArray* result4 = CntTest->Db()->FindLC(KSearchName4, fieldDef);
       
  1055 	test(result4->Count()==1);
       
  1056 	
       
  1057 	CContactIdArray* result5 = CntTest->Db()->FindLC(KSearchName5, fieldDef);
       
  1058 	test(result5->Count()==1);
       
  1059 		
       
  1060 	CleanupStack::PopAndDestroy(6); // fieldDef, 4 x results
       
  1061 
       
  1062     CntTest->CloseDatabase();
       
  1063     }
       
  1064 
       
  1065 LOCAL_C TInt AsyncFindByEmailTest(const TDesC& aEmailAddress)
       
  1066 	{
       
  1067 		//Returns the number of items that match the aEmailAddress
       
  1068 		//search criteria.
       
  1069 
       
  1070 		CContactItemFieldDef *fieldDef=new(ELeave) CContactItemFieldDef;
       
  1071 		CleanupStack::PushL(fieldDef);
       
  1072 		fieldDef->AppendL(KUidContactFieldEMail);
       
  1073 
       
  1074 		CAsyncFinder *finder=new(ELeave) CAsyncFinder;
       
  1075 		CleanupStack::PushL(finder);
       
  1076 		finder->ConstructL(CntTest->Db(),aEmailAddress,fieldDef);
       
  1077 
       
  1078 		CActiveScheduler::Start();
       
  1079 
       
  1080 		CContactIdArray* ids=finder->TakeContactIds();
       
  1081 
       
  1082 		TInt resultCount = ids->Count();
       
  1083 
       
  1084 		CleanupStack::PopAndDestroy(2); // finder, contactitemfielddef
       
  1085 		delete ids;
       
  1086 		return resultCount;
       
  1087 	}
       
  1088 
       
  1089 
       
  1090 void ResetContactDbL(CContactDatabase* aDb)
       
  1091 	{
       
  1092     CContactIdArray* idList = CContactIdArray::NewLC(aDb->SortedItemsL());
       
  1093     aDb->DeleteContactsL(*idList);
       
  1094     CleanupStack::PopAndDestroy(idList);
       
  1095 	}
       
  1096 
       
  1097 void GenerateContactsDbL(CContactDatabase* aDb,TUint acontactCount,TContactItemId* acontactIdArray)
       
  1098 	{
       
  1099     ResetContactDbL(aDb);    
       
  1100     for (TUint i = 0; i < acontactCount; i++)
       
  1101 		{
       
  1102 		TBuf<15> name;
       
  1103 		name.Format(_L("contact#%d"), i);
       
  1104 		CContactCard* contact = CContactCard::NewLC();        
       
  1105 		*(acontactIdArray + i) = aDb->AddNewContactL(*contact);        
       
  1106 		CleanupStack::PopAndDestroy(contact);
       
  1107 		}
       
  1108 	}
       
  1109 
       
  1110 void RollBackAndRecoverL()
       
  1111 	{
       
  1112 	test.Next(_L("Test that after a rollback, due to a failure in deleting, there is a recover"));
       
  1113 	TInt err = 0;
       
  1114 	TInt i = 0;
       
  1115 	CContactCard* contact = NULL;
       
  1116     const TInt contactCount = 10;
       
  1117 
       
  1118     TContactItemId contactIds[contactCount]; 
       
  1119 
       
  1120     CContactDatabase* contactDb = CContactDatabase::ReplaceL();
       
  1121     CleanupStack::PushL(contactDb);
       
  1122 
       
  1123 	// 1) Generate 10 contacts and keep the IDs in an array
       
  1124     GenerateContactsDbL(contactDb, contactCount, contactIds);
       
  1125   
       
  1126 	// 2) Delete the first 2 contacts
       
  1127     CContactIdArray* contactIdList = CContactIdArray::NewLC(contactDb->SortedItemsL());
       
  1128     contactDb->DeleteContactL(contactIds[0]);
       
  1129     contactDb->DeleteContactL(contactIds[1]);
       
  1130     CleanupStack::PopAndDestroy(contactIdList);
       
  1131     // 3) Check they are not in the list anymore using CContactIdArray::Find() and CContactDatabase::ReadContactLC()
       
  1132     contactIdList = CContactIdArray::NewLC(contactDb->SortedItemsL());
       
  1133 	test(contactIdList->Find(contactIds[0]) == KErrNotFound);
       
  1134     test(contactIdList->Find(contactIds[1]) == KErrNotFound);
       
  1135     TRAP(err, contact = static_cast<CContactCard*>(contactDb->ReadContactLC(contactIds[0])));
       
  1136 	test(err == KErrNotFound && contact == NULL);
       
  1137     TRAP(err, contact = static_cast<CContactCard*>(contactDb->ReadContactLC(contactIds[1])));
       
  1138 	test(err == KErrNotFound && contact == NULL);
       
  1139     CleanupStack::PopAndDestroy(contactIdList);
       
  1140 
       
  1141 	// 4) Try deleting a contact(that has already been deleted) using CContactDatabase::DeleteContactsL() .
       
  1142 	//	  We should get a KErrNotfound leave  which will cause a rollback 
       
  1143     contactIdList = CContactIdArray::NewLC(contactDb->SortedItemsL());
       
  1144     // now add one not existing
       
  1145     contactIdList->AddL(contactIds[0]); // this was deleted at step 1.
       
  1146     TRAP(err, contactDb->DeleteContactsL(*contactIdList)); 
       
  1147     test(err == KErrNotFound);
       
  1148 
       
  1149     // 5) Recover and check that after the rollback no contacts were deleted 
       
  1150 	contactDb->RecoverL();
       
  1151     for (i = 0; i < contactIdList->Count() - 1; i++) // all but last
       
  1152 		{
       
  1153         CContactCard* contact = NULL;
       
  1154         TRAP(err, contact = static_cast<CContactCard*>(contactDb->ReadContactL((*contactIdList)[i])));
       
  1155         if (contact)
       
  1156 			delete contact;
       
  1157 		test((err == KErrNone) && (contact != NULL));
       
  1158 		}
       
  1159     CleanupStack::PopAndDestroy(contactIdList);
       
  1160 
       
  1161 	// 1) Try deleting a contact(that is locked) using CContactDatabase::DeleteContactsL()
       
  1162 	//    We should get a KErrInUse leave  which will cause a rollback 
       
  1163     contactIdList = CContactIdArray::NewLC(contactDb->SortedItemsL());
       
  1164 
       
  1165     // open last one
       
  1166     TContactItemId lastItem = (*contactIdList)[contactIdList->Count() - 1];
       
  1167     contact = static_cast<CContactCard*>(contactDb->OpenContactL(lastItem));
       
  1168     CleanupStack::PushL(contact);
       
  1169 
       
  1170     TRAP(err, contactDb->DeleteContactsL(*contactIdList));
       
  1171     test(err == KErrInUse);
       
  1172 
       
  1173     CContactDbEventQueue* dbEventQueue = CContactDbEventQueue::NewL(contactDb);
       
  1174 	CleanupStack::PushL(dbEventQueue);
       
  1175 	dbEventQueue->Flush();
       
  1176 
       
  1177 	// 2) Recover and check that after the rollback no contacts were deleted 
       
  1178 	contactDb->RecoverL();
       
  1179 
       
  1180 	//wait until EContactDbObserverEventRecover message arrives
       
  1181     TContactDbObserverEvent event;
       
  1182 	while (dbEventQueue->ListenForEvent(3,event) && 
       
  1183 		   event.iType != EContactDbObserverEventRecover)
       
  1184         {} 
       
  1185 	CleanupStack::PopAndDestroy(dbEventQueue);
       
  1186 
       
  1187     contactDb->CloseContactL(lastItem);
       
  1188     CleanupStack::PopAndDestroy(contact);
       
  1189     // check all exist
       
  1190     for (i = 0; i < contactIdList->Count(); i++) 
       
  1191 		{
       
  1192         CContactCard* contact = NULL;
       
  1193         TRAP(err, contact = static_cast<CContactCard*>(contactDb->ReadContactL((*contactIdList)[i])));
       
  1194         if (contact) 
       
  1195 			delete contact;
       
  1196         test((err == KErrNone) && (contact != NULL));
       
  1197 		}
       
  1198 	
       
  1199     CleanupStack::PopAndDestroy(contactIdList);
       
  1200 
       
  1201     // ok, now everything is ok here
       
  1202     CleanupStack::PopAndDestroy(contactDb);
       
  1203 	}
       
  1204 
       
  1205 // This is a test case related to defect INC084290: Contact data being overwritten.
       
  1206 // It check that CommitContactL can be called multiple times without problem.
       
  1207 void CommitMultipleContactsL()
       
  1208 	{
       
  1209 	test.Next(_L("Test multiple calls to CommitContactL"));
       
  1210 	
       
  1211 	// Populate the database with 2 contacts
       
  1212 	_LIT(contactName1, "Bob");
       
  1213 	_LIT(contactName2, "Fred");
       
  1214 	
       
  1215 	CContactItem* item1 = CContactCard::NewLC();
       
  1216 	SetNameL(*item1, KUidContactFieldGivenName, contactName1, ETrue);
       
  1217 	TContactItemId itemId1 = CntTest->Db()->AddNewContactL(*item1);
       
  1218 	CleanupStack::PopAndDestroy(item1);
       
  1219 	
       
  1220 	CContactItem* item2 = CContactCard::NewLC();
       
  1221 	SetNameL(*item2, KUidContactFieldGivenName, contactName2, ETrue);
       
  1222 	TContactItemId itemId2 = CntTest->Db()->AddNewContactL(*item2);
       
  1223 	CleanupStack::PopAndDestroy(item2);
       
  1224 	
       
  1225 	CntTest->CloseDatabase();
       
  1226 	
       
  1227 	// Open the contacts and call CommitContactL
       
  1228 	CntTest->OpenDatabaseL();
       
  1229 	CContactItem *openedItem1 = CntTest->Db()->OpenContactL(itemId1);
       
  1230 	CleanupStack::PushL(openedItem1);
       
  1231 	CContactItem *openedItem2 = CntTest->Db()->OpenContactL(itemId2);
       
  1232 	CleanupStack::PushL(openedItem2);
       
  1233 	CntTest->Db()->CommitContactL(*openedItem1);
       
  1234 	CntTest->Db()->CommitContactL(*openedItem2);
       
  1235 	CleanupStack::PopAndDestroy(openedItem2);
       
  1236 	openedItem2 = 0;
       
  1237 	CleanupStack::PopAndDestroy(openedItem1);
       
  1238 	openedItem1 = 0;
       
  1239 	
       
  1240 	// Get the contacts and check their contents
       
  1241 	openedItem1 = CntTest->Db()->ReadContactLC(itemId1);
       
  1242 	CContactItemFieldSet& fields1=openedItem1->CardFields();
       
  1243 	TPtrC fieldText1=fields1[0].TextStorage()->Text();
       
  1244 	test(fieldText1==contactName1);
       
  1245 		
       
  1246 	openedItem2 = CntTest->Db()->ReadContactLC(itemId2);
       
  1247 	CContactItemFieldSet& fields2=openedItem2->CardFields();
       
  1248 	TPtrC fieldText2=fields2[0].TextStorage()->Text();
       
  1249 	test(fieldText2==contactName2);
       
  1250 		
       
  1251 	CleanupStack::PopAndDestroy(openedItem2);
       
  1252 	CleanupStack::PopAndDestroy(openedItem1);	
       
  1253 	}
       
  1254 
       
  1255 /**
       
  1256 
       
  1257 @SYMTestCaseID     PIM-T-DBASE2-0001
       
  1258 
       
  1259 */
       
  1260 
       
  1261 LOCAL_C void DoTestsL()
       
  1262     {
       
  1263 	test.Start(_L("@SYMTESTCaseID:PIM-T-DBASE2-0001 T_DBASE2"));
       
  1264 	TRAPD(err,TestFileSizeL());
       
  1265 	test(err==KErrNone);
       
  1266 	test.Next(_L("Create new database"));
       
  1267 	
       
  1268 	//Begin test procedure for DEF036083
       
  1269 	CntTest->CreateDatabaseL();
       
  1270 	TInt numberOfItemsWithEmailField = PopulateDatabaseForAsyncFindByEmailAddrTest(KTestEmailAddress);
       
  1271 	TInt numberOfItemsFoundWithEmailField = AsyncFindByEmailTest(KTestEmailAddress);
       
  1272 	test(numberOfItemsWithEmailField == numberOfItemsFoundWithEmailField);  //verify that all entries are found
       
  1273 	CntTest->CloseDatabase();
       
  1274 	CntTest->DeleteDatabaseL();
       
  1275 	//End test procedure for DEF036083
       
  1276 
       
  1277   	TRAP(err,TestFileUidL());
       
  1278 	CntTest->CreateDatabaseL();
       
  1279 	CntTest->CloseDatabase();
       
  1280 	TRAP(err,CreateExistingDatabaseTestL());
       
  1281 //
       
  1282 	CntTest->OpenDatabaseL();
       
  1283 	CntTest->DeleteAllTemplateFieldsL();
       
  1284 	DisplayModelVersionNumber();
       
  1285 	test(err==KErrNone);
       
  1286 	TRAP(err,PopulateDatabaseL(EFalse));
       
  1287 	test(err==KErrNone);
       
  1288 	LabelValidating();
       
  1289 	TRAP(err,NavigateL());
       
  1290 	test(err==KErrNone);
       
  1291 // group population
       
  1292 	TRAP(err,CreateBasicContactGroupsL());
       
  1293 	test(err==KErrNone);
       
  1294 // own card
       
  1295 	TRAP(err,CreateBasicOwnCardL());
       
  1296 	test(err==KErrNone);
       
  1297 // finding
       
  1298 	TRAP(err,FindL());
       
  1299 	test(err==KErrNone);
       
  1300 	TRAP(err,FindAsyncL());
       
  1301 	test(err==KErrNone);
       
  1302 	TRAP(err,FindAsyncInTextDefL());
       
  1303 	test(err==KErrNone);
       
  1304 
       
  1305 //
       
  1306 	TRAP(err,FindDefectL());
       
  1307 	test(err==KErrNone);
       
  1308 
       
  1309 	TRAP(err,FindScandinavianLettersL());
       
  1310 	test(err==KErrNone);
       
  1311 
       
  1312 	//test added for defect IC049017: NTT-FindAsyncL and FindLC do not search identitiy fields when KUidContactFieldMatchAll
       
  1313 	TRAP(err,FindUsingKUidContactFieldMatchAllL());
       
  1314 	test(err==KErrNone);
       
  1315 
       
  1316 // Following test create their own database
       
  1317 	TRAP(err,TestDeletingRecords());
       
  1318 	test(err==KErrNone);
       
  1319 // checking for templateRefId being updated in the Database tables.
       
  1320 	TRAP(err,CheckTemplateRefId());
       
  1321 	test(err==KErrNone);
       
  1322 
       
  1323 	TRAP(err,CrystalSortRegressionTestL());
       
  1324 //	TRAP(err,SortL());
       
  1325 //#pragma message ("Sorting testcode isn't run at the moment because the tests are invalid")
       
  1326 	test(err==KErrNone);
       
  1327 	TRAP(err,CountL(ETrue));
       
  1328 	test(err==KErrNone);
       
  1329 	TRAP(err,CountL(EFalse));
       
  1330 	test(err==KErrNone);
       
  1331 	TRAP(err,ContactIdArrayL());
       
  1332 	test(err==KErrNone);
       
  1333 	TRAP(err,ScanForChangesL());
       
  1334 	test(err==KErrNone);
       
  1335 	CntTest->CloseDatabase();
       
  1336 	CntTest->DeleteDatabaseL();
       
  1337 //
       
  1338 	CntTest->CreateDatabaseL();
       
  1339 	TRAP(err,PopulateDatabaseL(ETrue));
       
  1340 	test(err==KErrNone);
       
  1341 //
       
  1342 	TRAP(err,CurrentItemSupportTest());
       
  1343 	test(err==KErrNone);
       
  1344 //
       
  1345 	test(err==KErrNone);
       
  1346 //	TRAP(err,TestPhoneNumberMatchingL());
       
  1347 	test(err==KErrNone);
       
  1348 //
       
  1349 	TRAP(err,SortByTypeTest());
       
  1350 	test(err==KErrNone);
       
  1351 
       
  1352 	TRAP(err,DeleteManyContacts());
       
  1353 	test(err==KErrNone);
       
  1354 	TRAP(err,GroupCountRegressionTestL());
       
  1355 	test(err==KErrNone);
       
  1356 
       
  1357 	TRAP(err, DeleteContactDataRegressionTestL());
       
  1358 	test(err==KErrNone);
       
  1359 
       
  1360 	TRAP(err, FindContactWithApostropheL());
       
  1361 	test(err==KErrNone);
       
  1362 
       
  1363 	TRAP(err, RollBackAndRecoverL());
       
  1364 	test(err==KErrNone);
       
  1365 
       
  1366 	CntTest->CloseDatabase();
       
  1367 	CntTest->DeleteDatabaseL();
       
  1368 
       
  1369 	CntTest->CreateDatabaseL();
       
  1370 	TRAP(err, CommitMultipleContactsL());
       
  1371 	test(err==KErrNone);	
       
  1372 	CntTest->CloseDatabase();
       
  1373 	CntTest->DeleteDatabaseL();
       
  1374     }
       
  1375 
       
  1376 GLDEF_C TInt E32Main()
       
  1377 	{
       
  1378     CntTest=new(ELeave) CCntTest;
       
  1379 	CntTest->ConstructL(test,KDatabaseFileName);
       
  1380     TRAPD(err,DoTestsL());
       
  1381 	CntTest->EndTestLib(err);
       
  1382 	return KErrNone;
       
  1383     }