summaryrefslogtreecommitdiffstats
path: root/plugins/contacts/symbian/contactsmodel/tsrc/t_nomach.cpp
blob: daaa5b9b45a9606e776f5dae1942123edc8ed269 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
/*
* 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 "t_utils.h"
#include <coreappstest/testserver.h>

_LIT(KCntTestTitle,"T_NOMACH");
_LIT(KDatabaseFileName,"c:T_NOMACH");

#ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__ 
_LIT(KSrcDatabaseName, "z:\\t_old_contacts_original.cdb");
_LIT(KDatabaseName, "C:\\private\\10003A73\\t_old_contacts_in_use.cdb");
_LIT(KDatabaseOpenName, "C:t_old_contacts_in_use.cdb");
_LIT(KTestDbUpdate, "-- Test database update\n");
#endif //__SYMBIAN_CNTMODEL_USE_SQLITE__

_LIT(KTestName,"Test Name No %d");
_LIT(KTestAddress,"Test Address No %d");
_LIT(KTestFamilyName,"Test Family Name No %d");
_LIT(KTestEmail,"Test@Email.com No %d");
_LIT(KTestCountry,"Test Country No %d");
_LIT(KTestCompany,"Test Company No %d");
_LIT(KCntName,"Firstname");
_LIT(KCntSurname,"Surname");

_LIT(KTestNoPhoneMatchLibrary,"-- Regression testcode for DUG-4ZVNBW - MatchPhoneNumberL doesn't match correctly without CNTPHONE.DLL\n");
_LIT(KTestNewMatching,"-- Test matching; all following tests should match 1234567\n");
_LIT(KTestFaxSMSMatching,"-- Test adding fax and SMS numbers to the phone number match list, regression for COY-567J99\n");
_LIT(KSpeedDialSimpleTest,"-- Basic speed-dial tests.\n");
_LIT(KTestRemovingSpeedDials,"\n-- Test removing speed-dials; add five contacts, Set two speed dials - remove one & check the other is still there.\n");
_LIT(KTest11Digitmatching, "-- Test 11 digit matching\n");
_LIT(KTest15Digitmatching, "-- Test 15 digit matching\n");
_LIT(KTestEmbeddedZeroes, "-- Test Embedded Zeroes\n");

const TInt KMatch6Digits = 6;
const TInt KMatch7Digits = 7;
const TInt KMatch8Digits = 8;
const TInt KMatch10Digits = 10;
const TInt KMatch11Digits = 11;
const TInt KMatch12Digits = 12;
const TInt KMatch13Digits = 13;
const TInt KMatch14Digits = 14;
const TInt KMatch15Digits = 15;
const TInt KMatch16Digits = 16;

const TInt KTestContactsNum=10;

GLDEF_D CCntTest* CntTest=NULL;
GLDEF_D RTest test(KCntTestTitle);


LOCAL_C void SetNameL(CContactItem& aItem,TUid aType,const TDesC& aName, TBool aAddField)
//
// Set the contents of a text field, creating the field if required
//
	{
	CContactItemFieldSet& fieldSet=aItem.CardFields();
	const TInt pos=fieldSet.Find(aType);
	if (!aAddField && pos!=KErrNotFound)
		fieldSet[pos].TextStorage()->SetTextL(aName);
	else
		{
		CContactItemField* field=CContactItemField::NewLC(KStorageTypeText,aType);
   		field->SetMapping(KUidContactFieldVCardMapUnusedN);
		field->TextStorage()->SetTextL(aName);
		aItem.AddFieldL(*field);
		CleanupStack::Pop(field); 
		}
	}

LOCAL_C void PopulateDatabaseL(TInt aNumberToPopulate)
//
// Create and populate the database
//
	{
	CContactItem* templ = CntTest->Db()->ReadContactL(0);
	CleanupStack::PushL(templ);
	
	for (TInt ii=0;ii<aNumberToPopulate;ii++)
		{
		CContactItem* item=CContactCard::NewLC(templ);
		TBuf<20> name;
		name.Format(KTestName,ii);
   		SetNameL(*item,KUidContactFieldGivenName,name,EFalse);
		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,_L("11111"),EFalse);
		if (!(ii%2))
			{
			number.Format(_L("0181-%03d %04d"),(ii*8)%1000,((ii+11)*22)%10000);
	   		SetNameL(*item,KUidContactFieldPhoneNumber,_L("111"),EFalse); 
			number.Format(_L("01734-%06d"),(ii*123456)%1000000);
	   		SetNameL(*item,KUidContactFieldPhoneNumber,_L("1111"),EFalse);
			CContactItemFieldSet& itemFields = item->CardFields();
			for (TInt ii=0;ii<itemFields.Count();ii++)
				{
				CContactItemField& field = (itemFields)[ii];
				if (!itemFields[ii].Storage()->IsFull() && itemFields[ii].StorageType()==KStorageTypeText && 
					field.ContentType().ContainsFieldType(KUidContactFieldPhoneNumber))
					itemFields[ii].TextStorage()->SetTextL(_L("111111"));
				}
			}
		TBuf<32> address;
		address.Format(KTestAddress,ii);
		SetNameL(*item,KUidContactFieldAddress,address,EFalse);
//
		TBuf<32> familyName;
		familyName.Format(KTestFamilyName,ii);
		SetNameL(*item,KUidContactFieldFamilyName,familyName,EFalse);
//
		TBuf<32> email;
		email.Format(KTestEmail,ii);
		SetNameL(*item,KUidContactFieldEMail,email,EFalse);
//
		TBuf<32> country;
		country.Format(KTestCountry,ii);
		SetNameL(*item,KUidContactFieldCountry,country,EFalse);
//	
		TBuf<32> company;
		company.Format(KTestCompany,ii);
		SetNameL(*item,KUidContactFieldCompanyName,company,EFalse);
//	
		CntTest->Db()->AddNewContactL(*item); 
		CleanupStack::PopAndDestroy(item); 

		test.Printf(_L("."));	// Just to show some life
		}
	CleanupStack::PopAndDestroy(templ);
	CntTest->Db()->CompactL();
	}






// Delete the current contacts database and create a new one
// 
LOCAL_C void ResetDatabaseL()
	{
	// Reset all server side speed dials ;-))) 
	CntTest->Db()->ResetServerSpeedDialsL();

	CntTest->CloseDatabase();
	CntTest->DeleteDatabaseL();
	CntTest->CreateDatabaseL();
	CntTest->OpenDatabaseL();	
	}


LOCAL_C TContactItemId CreateContactL(const TDesC& aFirstName, const TDesC& aFamilyName, const TDesC& aPhoneNo, const TDesC& aMobileNo)
	{
	test.Printf(_L("\tCreating contact %S %S, phone: %S mobile: %S\n"), &aFirstName, &aFamilyName, &aPhoneNo, &aMobileNo);
	CContactItem* item=CContactCard::NewLC();
	SetNameL(*item,KUidContactFieldGivenName,KUidContactFieldVCardMapUnusedN,aFirstName,ETrue);
	SetNameL(*item,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,aFamilyName,ETrue);
	SetNameL(*item,KUidContactFieldPhoneNumber,KUidContactFieldVCardMapTEL,aPhoneNo,ETrue);
	SetNameL(*item,KUidContactFieldPhoneNumber,KUidContactFieldVCardMapCELL,aMobileNo,ETrue);
	item->SetTemplateRefId(KGoldenTemplateId);
	TContactItemId id=CntTest->Db()->AddNewContactL(*item);
	CleanupStack::PopAndDestroy(item); 
	return id;
	}

LOCAL_C void CheckPhoneMatchL(const TDesC& aPhoneNumberToMatch, TInt aNumberOfMatchDigits, TInt aExpectedNumOfMatches)
	{
	TBuf<256> testCase;
	_LIT(KFormat,"Checking %d matches to %S, matching %d digits");
	testCase.Format(KFormat, aExpectedNumOfMatches, &aPhoneNumberToMatch, aNumberOfMatchDigits);
	test.Next(_L(" "));

	CContactDatabase& db = *(CntTest->Db());
	CContactIdArray* array = db.MatchPhoneNumberL(aPhoneNumberToMatch,aNumberOfMatchDigits);
	CleanupStack::PushL(array);
	const TInt numberOfMatches = array->Count();
	CleanupStack::PopAndDestroy(array);
	
	
	TInt sfd = db.MachineId();
	// OverrideMachineUniqueId
	
	
	test(numberOfMatches==aExpectedNumOfMatches);
	}

/** 
Testcode for Graham's new API

These all match 1234567:
*#42# 0401234567 p123
*#42# +358401234567 p123
*61 0401234567
*61 +358401234567
+358401234567 +3
+358401234567 p123

*/
LOCAL_C void TestNewMatchingL()
	{
	ResetDatabaseL();

	const TInt KLastThreeDigits =3;
	//These numbers match 1234567
	_LIT(KCntDTMFNumber1,"*#42# 0401234567 p123");
	_LIT(KCntDTMFNumber2,"*#42#+358401234567 p123");
	_LIT(KCntDTMFNumber3,"*61 0401234567");
	_LIT(KCntDTMFNumber4,"*61 +358401234567");
	_LIT(KCntDTMFNumber5,"+358401234567 +3");
	_LIT(KCntDTMFNumber6,"+358401234567 p123");
	_LIT(KCntMatch1to7ExtraCharacters,"mobile 12 345-67");
	_LIT(KCntMatch1to7Brackets,"(020) 0123-4567");
	_LIT(KCntMatch1to7TooManyNumbers,"123456789012345678901234567");
	//These shouldn't match 1234567
	_LIT(KCntDTMFNumber7,"*#42# 0401234567#p123");//empty
	_LIT(KCntDTMFNumber8,"*12345+0401234567");    //matches 12345
	_LIT(KCntDTMFNumber9,"*+123+456+++++++++++"); //matches 123
	//Graham's possible defects
	_LIT(KCntPossibleDefect,"70000");
	_LIT(KCntZeroAtEnd,"020 5632700");
	//Match numbers
	_LIT(KCntMatch1to7,"1234567");
	_LIT(KCntMatch1to3,"123");
	_LIT(KCntMatch700,"700");
	//Spaces at the start
	_LIT(KCntSpaceInNumber,"   0 2 0      7 1 2 0  5 6 7 8    ");
	_LIT(KCntSpaceMatch,"02071205678");
	_LIT(KCntSpaceInNumberIntl,"   +44 7447 065 472");
	_LIT(KCntSpaceInNumberIntlMatch,"+446447065472");
	_LIT(KCntSpaceWorstCase,"              ");
	_LIT(KCntNoRealDigitsInNumber,"Lycos SMS");

	_LIT(KCntShortNumber1,"789");
	_LIT(KCntShortNumber2,"456");

	_LIT(KCntEndingByShortNumber1,"+44(0)32465764789");
	_LIT(KCntEndingByShortNumber2,"+443216568731456");

	_LIT(KCntMatchShortNumber1,"789"); // must not match other number ending with 789
	_LIT(KCntMatchShortNumber2,"456"); // must not match other number ending with 456

	CreateContactL(KCntName,KCntSurname,KCntShortNumber1,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KCntShortNumber2,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KCntEndingByShortNumber1,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KCntEndingByShortNumber2,KNullDesC);
	

	CreateContactL(KCntName,KCntSurname,KCntDTMFNumber1,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KCntDTMFNumber2,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KCntDTMFNumber3,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KCntDTMFNumber4,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KCntDTMFNumber5,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KCntDTMFNumber6,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KCntDTMFNumber7,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KCntDTMFNumber8,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KCntDTMFNumber9,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KCntPossibleDefect,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KCntMatch1to7ExtraCharacters,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KCntMatch1to7Brackets,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KCntMatch1to7TooManyNumbers,KNullDesC);
	TContactItemId id = CreateContactL(KCntName,KCntSurname,KCntZeroAtEnd,KNullDesC);

	CheckPhoneMatchL(KCntMatch1to7,KMatch7Digits,9);
	CheckPhoneMatchL(KCntMatch1to7,KLastThreeDigits,9);	// no contact with 567 as phone number  
	CheckPhoneMatchL(KCntMatch1to7,KMatch7Digits,9);
	CheckPhoneMatchL(KCntMatch1to7,KLastThreeDigits,9); // no contact with 567 as phone number  
	
	CheckPhoneMatchL(KCntMatch1to3,KMatch7Digits,1);
	CheckPhoneMatchL(KCntMatch1to3,KMatch7Digits,1);

	CheckPhoneMatchL(KCntPossibleDefect,KMatch7Digits,1);
	CheckPhoneMatchL(KCntZeroAtEnd,KMatch7Digits,1);
	CheckPhoneMatchL(KCntMatch700,KLastThreeDigits,0);  // no contact with 700 as phone number at this point 
	CheckPhoneMatchL(KCntZeroAtEnd,KMatch7Digits,1);
		
	CheckPhoneMatchL(KCntNoRealDigitsInNumber,KMatch7Digits,0);
	
	CheckPhoneMatchL(KCntMatchShortNumber1,KLastThreeDigits,1); //
	CheckPhoneMatchL(KCntMatchShortNumber2,KLastThreeDigits,1); //

	// Simulate a synchronisation (increment the access count)
	CContactItem* item = CntTest->Db()->OpenContactLX(id);
	item->IncAccessCount();
	CntTest->Db()->CommitContactL(*item);
	CleanupStack::PopAndDestroy(); //lock record
	delete item;
	
	// Delete the contact and verify that it has been removed from the phone match table 
	CntTest->Db()->DeleteContactL(id);
	CheckPhoneMatchL(KCntZeroAtEnd,KMatch7Digits,0);

	CreateContactL(KCntName,KCntSurname,KCntSpaceInNumber,KNullDesC);
	CheckPhoneMatchL(KCntSpaceMatch,KMatch7Digits,1);	
	CreateContactL(KCntName,KCntSurname,KCntSpaceInNumberIntl,KNullDesC);
	CheckPhoneMatchL(KCntSpaceInNumberIntlMatch,KMatch7Digits,1);	
	CreateContactL(KCntName,KCntSurname,KCntSpaceWorstCase,KNullDesC);
	}


// Regression testcode for 
// DUG-4ZVNBW "MatchPhoneNumberL doesn't match correctly without CNTPHONE.DLL"
//
// Remove CNTPHONE.DLL before running this test to verify
//
LOCAL_C void TestNoPhoneMatchLibraryL()
	{
	ResetDatabaseL();
	_LIT(KCntNumberWithSpaces,"+44  020 7563 2000");
	_LIT(KCntNumberWithoutSpaces,"02075632000");
	CreateContactL(KCntName,KCntSurname,KCntNumberWithSpaces,KNullDesC);
	CheckPhoneMatchL(KCntNumberWithoutSpaces,KMatch7Digits,1);
	}


LOCAL_C TContactItemId CreateFaxSMSContactL(const TDesC& aFirstName, const TDesC& aFamilyName, const TDesC& aFaxNo, const TDesC& aSMSNo)
	{
	CContactItem* item=CContactCard::NewLC();
	SetNameL(*item,KUidContactFieldGivenName,KUidContactFieldVCardMapUnusedN,aFirstName,ETrue);
	SetNameL(*item,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,aFamilyName,ETrue);
	SetNameL(*item,KUidContactFieldFax,KUidContactFieldVCardMapFAX,aFaxNo,ETrue);
	SetNameL(*item,KUidContactFieldSms,KUidContactFieldVCardMapTEL,aSMSNo,ETrue);
	item->SetTemplateRefId(KGoldenTemplateId);
	TContactItemId id=CntTest->Db()->AddNewContactL(*item);
	CleanupStack::PopAndDestroy(item); 
	return id;
	}


/** 
Regression testcode for defect COY-567J99 "Phone number matching does not match Fax field"
Testcode for adding fax and SMS numbers to the phone number match list
*/
LOCAL_C void TestFaxSMSMatchingL()
	{
	ResetDatabaseL();

	_LIT(KCntFaxNumber1,"020 85858585");
	_LIT(KCntFaxNumber2,"020 85858432");
	_LIT(KCntSMSNumber1,"+442085858432");
	_LIT(KCntSMSNumber2,"+442085858585");
	
	_LIT(KCntDuplicateNumber,"0208 5858585");
	_LIT(KCntNewSMSNumber,"020 85969696");
	
	TContactItemId one = CreateFaxSMSContactL(KCntName,KCntSurname,KCntFaxNumber1,KCntSMSNumber1);
	TContactItemId two = CreateFaxSMSContactL(KCntName,KCntSurname,KCntFaxNumber2,KCntSMSNumber2);
	
	//check that there are only 2 matches
	CheckPhoneMatchL(KCntDuplicateNumber,9,2);
	
	// delete contact one 
	CntTest->Db()->DeleteContactL(one);
	
	//check that there is only 1 match now
	CheckPhoneMatchL(KCntDuplicateNumber,9,1);

	//edit item two
	CContactItem* item = CntTest->Db()->OpenContactL(two);
	CleanupStack::PushL(item);
	CContactItemFieldSet& fieldSet = item->CardFields();
	TInt fieldId=fieldSet.Find(KUidContactFieldSms);
	CContactItemField& field = fieldSet[fieldId];
	field.TextStorage()->SetTextL(KCntNewSMSNumber);
	CntTest->Db()->CommitContactL(*item);
	CleanupStack::PopAndDestroy(item);
	
	//check that there is no matches now
	CheckPhoneMatchL(KCntDuplicateNumber,9,0);
	}


// Check that the speed dial at position aSpeedDialPosition matches the aExpectedId
// and the contents of the field with aFieldId is the same in the speed dial.
//
LOCAL_C void CheckSpeedDialL(TInt aSpeedDialPosition, CContactItem& aContact, TInt aFieldId)
	{
	HBufC* buf=HBufC::NewLC(100);	
	TPtr fieldContents=buf->Des();
	
	TContactItemId id = CntTest->Db()->GetSpeedDialFieldL(aSpeedDialPosition, fieldContents);
	TPtrC actualContents =(aContact.CardFields()[aFieldId].TextStorage()->Text());
	test(id==aContact.Id());
	test(actualContents==fieldContents);

	CleanupStack::PopAndDestroy(); //buf
	}

/**
 * Check that speed dials are working correctly;
 * Add first contact to speed dial 1, add second contact to speed dial 9.
 * Check speed dial 1 still matches contact 1 after adding speed dial
 * Check persistance of speed dial list
 * Check overwriting old speed dial with new contact id
 * Check deletion of contact removes all existing speed dials
 */
LOCAL_C void SpeedDialSimpleTest()
	{
	ResetDatabaseL();
	TRAP_IGNORE(PopulateDatabaseL(KTestContactsNum));
	
	const CContactIdArray* sortedItems = CntTest->Db()->SortedItemsL();

	// first item in position 1
	CContactItem* firstItem = CntTest->Db()->OpenContactL((*sortedItems)[0]);
	CleanupStack::PushL(firstItem);
	TInt fieldId=5;
	const TInt speedDialPositionOne=1;
	CntTest->Db()->SetFieldAsSpeedDialL(*firstItem, fieldId, speedDialPositionOne);
	CheckSpeedDialL(speedDialPositionOne,*firstItem,fieldId);

	// second item in position 2
	CContactItem* secondItem = CntTest->Db()->OpenContactL((*sortedItems)[1]);
	CleanupStack::PushL(secondItem);
	fieldId=5;
	const TInt speedDialPositionNine=9;
	CntTest->Db()->SetFieldAsSpeedDialL(*secondItem, fieldId, speedDialPositionNine);
	CheckSpeedDialL(speedDialPositionNine,*secondItem,fieldId);

	// wrong answers..... 
	CheckSpeedDialL(speedDialPositionOne,*firstItem,5);
	
	// check persistance
	CntTest->CloseDatabase();
	CntTest->OpenDatabaseL();
	CheckSpeedDialL(speedDialPositionOne,*firstItem,5);
	CheckSpeedDialL(speedDialPositionNine,*secondItem,5);

	// check overwriting old speed dial (third contact, speed dial 1)
	const CContactIdArray* newSortedItems = CntTest->Db()->SortedItemsL();
	CContactItem* thirdItem = CntTest->Db()->OpenContactL((*newSortedItems)[2]);
	CleanupStack::PushL(thirdItem);
	fieldId=5;
	CntTest->Db()->SetFieldAsSpeedDialL(*thirdItem, fieldId, speedDialPositionOne);
	CheckSpeedDialL(speedDialPositionOne,*thirdItem,5);

	// delete contact and check that speed dials have been removed
	CntTest->Db()->DeleteContactL((*newSortedItems)[2]);
	HBufC* temp8=HBufC::NewLC(100);	
	TPtr testText8=temp8->Des();
	TContactItemId eightId = CntTest->Db()->GetSpeedDialFieldL(speedDialPositionOne, testText8);
	test(eightId==KNullContactId);
	test(testText8==KNullDesC);

	// modify a contact with a speed dial - but do not change the relavent field.
	CContactItem* fourthItem = CntTest->Db()->OpenContactL((*newSortedItems)[2]);
	CleanupStack::PushL(fourthItem);
	fieldId=5;
	
	CntTest->Db()->SetFieldAsSpeedDialL(*fourthItem, fieldId, speedDialPositionOne);
	TInt fieldPosOfSpeedDial = fourthItem->CardFields().Find(KUidSpeedDialOne);
	test(fieldPosOfSpeedDial != KErrNotFound);
  	
	CContactItem* fifthItem = CntTest->Db()->OpenContactL(fourthItem->Id());
	CleanupStack::PushL(fifthItem);

	// remove the first field in the list.
	fieldPosOfSpeedDial = fifthItem->CardFields().Find(KUidSpeedDialOne);

	fifthItem->CardFields().Remove(1);
	CntTest->Db()->CommitContactL(*fifthItem);
	
	CleanupStack::PopAndDestroy(6); // firstItem, secondItem, thirdItem, fourthItem, fifthItem, temp8
	}


/**
 *Add five contacts.
 * Set two speed dials - remove one & check the other is still there.
 */
LOCAL_C void TestRemovingSpeedDialsL()
	{
	ResetDatabaseL();
	PopulateDatabaseL(KTestContactsNum);
	const CContactIdArray* sortedItems = CntTest->Db()->SortedItemsL(); //doesn't take ownership
	const TInt speedDialPositionOne=1;
	const TInt speedDialPositionNine=9;

	
	const TContactItemId firstId = (*sortedItems)[3];
	const TContactItemId secondId = (*sortedItems)[5];

	CContactItem* first = CntTest->Db()->OpenContactL(firstId);
	CleanupStack::PushL(first);
	CContactItemFieldSet& aFieldSet = first->CardFields();
	for(TInt fieldLoop=0;fieldLoop<aFieldSet.Count();fieldLoop++)
		{
		CContactItemField& field = aFieldSet[fieldLoop];
		if (field.ContentType().ContainsFieldType(KUidContactFieldPhoneNumber))
			{
			// change it...
			field.TextStorage()->SetTextL(_L("956431458"));
			}				
		}
	CntTest->Db()->CommitContactL(*first);
	CleanupStack::PopAndDestroy(); //first

	first = CntTest->Db()->OpenContactL(firstId);
	CleanupStack::PushL(first);	
	TInt fieldId=first->CardFields().Find(KUidContactFieldPhoneNumber);
	CntTest->Db()->SetFieldAsSpeedDialL(*first, fieldId, speedDialPositionOne);

	CContactItem* second = CntTest->Db()->OpenContactL(secondId);
	CleanupStack::PushL(second);	
	TInt fieldId2=first->CardFields().Find(KUidContactFieldPhoneNumber);
	CntTest->Db()->SetFieldAsSpeedDialL(*second, fieldId2, speedDialPositionNine);

	// check they are all established ok
	HBufC* buf=HBufC::NewLC(100);	
	TPtr fieldContents=buf->Des();
	TContactItemId	id = CntTest->Db()->GetSpeedDialFieldL(speedDialPositionOne, fieldContents);
	test(id==firstId);
	id = CntTest->Db()->GetSpeedDialFieldL(speedDialPositionNine, fieldContents);
	test(id==secondId);
	CleanupStack::PopAndDestroy(); //buf

	CntTest->Db()->RemoveSpeedDialFieldL(firstId, speedDialPositionOne);

	HBufC* buf2=HBufC::NewLC(100);	
	TPtr phoneNum=buf2->Des();
	TContactItemId idOne = CntTest->Db()->GetSpeedDialFieldL(speedDialPositionOne, phoneNum);
	test(idOne==KNullContactId);
	test(phoneNum==KNullDesC);
	CleanupStack::PopAndDestroy(); //buf2


	HBufC* buf3=HBufC::NewLC(100);	
	TPtr phoneNo2=buf3->Des();
	TContactItemId id2 = CntTest->Db()->GetSpeedDialFieldL(speedDialPositionNine, phoneNo2);
	test(id2==secondId);
	CleanupStack::PopAndDestroy(); //buf

	CntTest->Db()->RemoveSpeedDialFieldL(secondId, speedDialPositionNine);

	HBufC* buf4=HBufC::NewLC(100);	
	TPtr phoneNo3=buf4->Des();
	id = CntTest->Db()->GetSpeedDialFieldL(speedDialPositionNine, phoneNo3);
	test(id==KNullContactId);
	test(phoneNum==KNullDesC);
	CleanupStack::PopAndDestroy(); //buf4

	CleanupStack::PopAndDestroy(2); //first, second
	}

/**
 * Verifies that matching of 11-digit phone number matching works correctly
 */
LOCAL_C void Test11DigitMatchingL()
	{
	ResetDatabaseL();

	_LIT(K11DigitTestNumber1,"20 7582 24220");
	_LIT(K11DigitTestNumber2,"020 7582 2422");
	_LIT(K11DigitTestNumber3,"020 7582 2381");
	_LIT(K11DigitTestNumber4,"120 7582 2381");
	_LIT(K11DigitTestNumber5,"9120 7582 2381");

	CreateContactL(KCntName,KCntSurname,K11DigitTestNumber1,KNullDesC);
	CreateContactL(KCntName,KCntSurname,K11DigitTestNumber2,KNullDesC);
	CreateContactL(KCntName,KCntSurname,K11DigitTestNumber3,KNullDesC);
	CreateContactL(KCntName,KCntSurname,K11DigitTestNumber4,KNullDesC);
	CreateContactL(KCntName,KCntSurname,K11DigitTestNumber5,KNullDesC);

	//Match numbers
	_LIT(K11DigitMatch1,"020 7582 2422");
	_LIT(K11DigitMatch2,"20 7582 24220");
	_LIT(K11DigitMatch3,"020 7582 2381");
	_LIT(K11DigitMatch4,"120 7582 2381");
	_LIT(K11DigitMatch5,"9120 7582 2381");
	_LIT(K11DigitMatch6,"20 7582 2381");

	CheckPhoneMatchL(K11DigitMatch1,KMatch10Digits,1);
	CheckPhoneMatchL(K11DigitMatch1,KMatch11Digits,1);

	CheckPhoneMatchL(K11DigitMatch2,KMatch10Digits,1);
	CheckPhoneMatchL(K11DigitMatch2,KMatch11Digits,1);

	CheckPhoneMatchL(K11DigitMatch3,KMatch10Digits,3);
	CheckPhoneMatchL(K11DigitMatch3,KMatch11Digits,1);

	CheckPhoneMatchL(K11DigitMatch4,KMatch10Digits,3);
	CheckPhoneMatchL(K11DigitMatch4,KMatch11Digits,2);

	CheckPhoneMatchL(K11DigitMatch5,KMatch12Digits,1);
	CheckPhoneMatchL(K11DigitMatch5,KMatch13Digits,1);

	CheckPhoneMatchL(K11DigitMatch6,KMatch10Digits,3);
	CheckPhoneMatchL(K11DigitMatch6,KMatch11Digits,1);
	}

/**
 * Verifies that 15 digit phone numbers are matched correctly.
 */
LOCAL_C void Test15DigitMatchingL()
	{
	ResetDatabaseL();

	_LIT(K15DigitTestNumber1,"0086 207 3453 3454");
	_LIT(K15DigitTestNumber2,"8186 207 3453 3454");
	_LIT(K15DigitTestNumber3,"8620 734 5334 5400");

	CreateContactL(KCntName,KCntSurname,K15DigitTestNumber1,KNullDesC);
	CreateContactL(KCntName,KCntSurname,K15DigitTestNumber2,KNullDesC);
	CreateContactL(KCntName,KCntSurname,K15DigitTestNumber3,KNullDesC);

	//Match numbers
	_LIT(K15DigitMatch1,"0086 207 3453 3454");
	_LIT(K15DigitMatch2,"86 207 3453 3454");
	_LIT(K15DigitMatch3,"8186 207 3453 3454");
	_LIT(K15DigitMatch4,"08186 207 3453 3454");

	CheckPhoneMatchL(K15DigitMatch1,KMatch15Digits,1);
	CheckPhoneMatchL(K15DigitMatch1,KMatch14Digits,1);
	CheckPhoneMatchL(K15DigitMatch1,KMatch13Digits,2);

	CheckPhoneMatchL(K15DigitMatch2,KMatch13Digits,2);

	CheckPhoneMatchL(K15DigitMatch3,KMatch15Digits,1);

	CheckPhoneMatchL(K15DigitMatch4,KMatch16Digits,1);
	CheckPhoneMatchL(K15DigitMatch4,KMatch15Digits,1);
	}


/**
 * Verifies that phone numbers are matched correctly if they
 * have leading, trailing and embedded zeroes.
 */
LOCAL_C void TestEmbeddedZeroesL()
	{
	ResetDatabaseL();

	_LIT(KEmbeddedZeroesTestNumber1,"9999 9990 0999 999");
	_LIT(KEmbeddedZeroesTestNumber2,"9000 0000 0000 000");
	_LIT(KEmbeddedZeroesTestNumber3,"0000 0000 0000 000");
	_LIT(KEmbeddedZeroesTestNumber4,"0000 0000 0000 009");
	_LIT(KEmbeddedZeroesTestNumber5,"9 9000 000");
	_LIT(KEmbeddedZeroesTestNumber6,"9000 000");

	CreateContactL(KCntName,KCntSurname,KEmbeddedZeroesTestNumber1,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KEmbeddedZeroesTestNumber2,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KEmbeddedZeroesTestNumber3,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KEmbeddedZeroesTestNumber4,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KEmbeddedZeroesTestNumber5,KNullDesC);
	CreateContactL(KCntName,KCntSurname,KEmbeddedZeroesTestNumber6,KNullDesC);

	//Match numbers
	_LIT(KEmbeddedZeroMatch1,"9999 9990 0999 999");
	_LIT(KEmbeddedZeroMatch2,"9000 0000 0000 000");
	_LIT(KEmbeddedZeroMatch3,"0000 0000 0000 000");
	_LIT(KEmbeddedZeroMatch4,"0000 0000 0000 009");
	_LIT(KEmbeddedZeroMatch5,"9 9000 000");
	_LIT(KEmbeddedZeroMatch6,"9000 000");
	_LIT(KEmbeddedZeroMatch7,"0000 000");

	CheckPhoneMatchL(KEmbeddedZeroMatch1,KMatch15Digits,1);
	CheckPhoneMatchL(KEmbeddedZeroMatch2,KMatch15Digits,1);
	CheckPhoneMatchL(KEmbeddedZeroMatch3,KMatch15Digits,1);
	CheckPhoneMatchL(KEmbeddedZeroMatch4,KMatch15Digits,1);
	CheckPhoneMatchL(KEmbeddedZeroMatch5,KMatch15Digits,1);
	CheckPhoneMatchL(KEmbeddedZeroMatch5,KMatch8Digits,1);
	CheckPhoneMatchL(KEmbeddedZeroMatch6,KMatch7Digits,2);
	CheckPhoneMatchL(KEmbeddedZeroMatch7,KMatch7Digits,1);
	CheckPhoneMatchL(KEmbeddedZeroMatch6,KMatch6Digits,2);
	}


#ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__ 	//we mark this since the new contact database based on SQLite 
                         		//as the porting on SQLite database allows the thorough DC break and
                         		//doesn't support the feature of database update from old database on
                         		//Symbian DBMS.
void TestDbUpdateL()
	{

    RPIMTestServer serv;
    User::LeaveIfError(serv.Connect());
    serv.CopyFileL(KSrcDatabaseName, KDatabaseName);

    serv.Close();

	// Contact model must open and upgrade database
	test.Printf(_L("Opening and upgrading database\n"));
	CContactDatabase* db = NULL; 
	db = CContactDatabase::OpenL(KDatabaseOpenName);

	// Add a contact with a 15 digit phone number and match the same number
	_LIT(K15DigitTestNumber,"0086 207 3453 1212");
	_LIT(K15DigitMatch,"0086 207 3453 1212");
	CreateContactL(KCntName,KCntSurname,K15DigitTestNumber,KNullDesC);
	CheckPhoneMatchL(K15DigitMatch,KMatch15Digits,1);

	delete db;
	db = NULL;
	}
#endif // __SYMBIAN_CNTMODEL_USE_SQLITE__ 

/**

@SYMTestCaseID     PIM-T-NOMACH-0001

*/

LOCAL_C void DoTestsL()
    {
	test.Start(_L("@SYMTESTCaseID:PIM-T-NOMACH-0001 T_NOMACH"));


	CTestRegister* TempFiles = CTestRegister::NewLC();
	

#ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
	TempFiles->RegisterL(KDatabaseOpenName, EFileTypeCnt);
#endif // __SYMBIAN_CNTMODEL_USE_SQLITE__
	
	TempFiles->RegisterL(KDatabaseFileName, EFileTypeCnt);

	CntTest->CreateDatabaseL();
    TInt err;
    
#ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__ //see comments above function TestDbUpdateL 
	test.Printf(KTestDbUpdate);
	TRAP(err,TestDbUpdateL());
	test(err==KErrNone);
#endif // __SYMBIAN_CNTMODEL_USE_SQLITE__



     


	test.Printf(KTest11Digitmatching);
	TRAP(err,Test11DigitMatchingL());
	test(err==KErrNone);

	test.Printf(KTest15Digitmatching);
	TRAP(err,Test15DigitMatchingL());
	test(err==KErrNone);

	test.Printf(KTestEmbeddedZeroes);
	TRAP(err,TestEmbeddedZeroesL());
	test(err==KErrNone);

	test.Printf(KTestNoPhoneMatchLibrary);
	TestNoPhoneMatchLibraryL();

	test.Printf(KTestNewMatching);
	TestNewMatchingL();


	test.Printf(KTestFaxSMSMatching);
	TestFaxSMSMatchingL();

	test.Printf(KSpeedDialSimpleTest);
	TRAP(err,SpeedDialSimpleTest());
	test(err==KErrNone);

	test.Printf(KTestRemovingSpeedDials);
	TRAP(err,TestRemovingSpeedDialsL());
	test(err==KErrNone);

	CntTest->CloseDatabase();
	CntTest->DeleteDatabaseL();

	CleanupStack::PopAndDestroy(TempFiles);
	
	// stop efsrv.lib warning on 8.1a wins
	TEntry dummy;
	(void)dummy.IsTypeValid();
    }


	
GLDEF_C TInt E32Main()
	{
    CntTest=new(ELeave) CCntTest;
	CntTest->ConstructL(test,KDatabaseFileName);
    TRAPD(err,DoTestsL());
	test.Printf(_L("\n"));
	CntTest->EndTestLib(err);

	return KErrNone;
    }