diff -r fd64c38c277d -r b46a585f6909 phonebookengines_old/contactsmodel/tsrc/t_iccentry.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines_old/contactsmodel/tsrc/t_iccentry.cpp Fri Jun 11 13:29:23 2010 +0300 @@ -0,0 +1,945 @@ +// Copyright (c) 2001-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 +#include +#include +#include +#include +#include + +#include "T_UTILS.H" +#include "./TestSyncPlugIn/cnttestsynchroniser.h" + +// include templates for CleanupResetAndDestroyPushL(T) +#include "cntviewprivate.h" + + +/** + * @file + * Test harness for CContactICCEntry and MContactSynchroniser interface. + * todo Find out why telephone field won't match template correctly + * (Maybe the ICC slot field needs to be added to the "golden" template) + * + */ + +_LIT(KDatabaseFileName,"C:T_ICCENTRY"); + +_LIT(KTestName,"Basic tests for CContactICCEntry"); +_LIT(KGivenName,"Given"); +_LIT(KGivenEditName,"EditedName"); +_LIT(KTelephoneNum,"020 79460111"); +_LIT(KTelephoneNumModified,"020 79460222"); +_LIT(KTemplateName,"SIM Card Contacts"); + +_LIT(KPluginName,"phone book synchronizer Implementation"); +_LIT(KTestPluginName,"Test phone book synchronizer Implementation"); + +CCntTest* CntTest=NULL; +LOCAL_D RTest test(KTestName); + +LOCAL_D CContactTestSynchroniser* synchroniser; +LOCAL_D CContactSyncChecker* syncChecker; + +LOCAL_C TInt findWordSplitterL(TAny *aParams) + { + SFindInTextDefWordParser *parser=(SFindInTextDefWordParser *)aParams; + parser->iWordArray->AppendL(*parser->iSearchString); + return(KErrNone); + } + +CContactIdArray* TestFindL(CContactDatabase& aDatabase, const TDesC& aText, const CContactItemFieldDef *aFieldDef, RTest& aTest) + { + CContactIdArray* retval = NULL; + + retval = aDatabase.FindLC(aText, aFieldDef); + aTest(retval == NULL); + CleanupStack::Pop( retval ); + + return retval; + } + +CContactIdArray* TestFindInTextDefL(CContactDatabase& aDatabase, const MDesCArray& aFindWords,CContactTextDef* aTextDef, const TCallBack &aWordParserCallback, RTest& aTest) + { + CContactIdArray* retval = NULL; + retval = aDatabase.FindInTextDefLC(aFindWords, aTextDef, aWordParserCallback); + aTest(retval==NULL); + CleanupStack::Pop( retval ); + return retval; + } + +/** + * Test Finding ICC Contacts when the ICC is locked. + * @param aDb Contact database + */ + +void TestFindingL(CContactDatabase& aDb) + { + test.Next(_L("Test FindLC")); + + syncChecker->SetValidateResponseL(MContactSynchroniser::ERead,KErrLocked); + syncChecker->SetValidateResponseL(MContactSynchroniser::ESearch,KErrLocked); + + CContactItemFieldDef* fieldDef=new(ELeave) CContactItemFieldDef; + CleanupStack::PushL(fieldDef); + fieldDef->AppendL(KUidContactFieldFamilyName); + + + TRAPD(err,TestFindL(aDb, KGivenEditName, fieldDef, test) ); + test(err==KErrLocked); + CleanupStack::PopAndDestroy(fieldDef); + + CContactItemFieldDef* fieldDef2=new(ELeave) CContactItemFieldDef; + CleanupStack::PushL(fieldDef2); + fieldDef2->AppendL(KUidContactFieldPhoneNumber); + TRAP(err, TestFindL(aDb, KTelephoneNum, fieldDef2, test) ); + test(err==KErrLocked); + CleanupStack::PopAndDestroy(fieldDef2); + + test.Next(_L("Test FindInTextDefL")); + + TCallBack callBack(findWordSplitterL); + CContactTextDef* textDef=CContactTextDef::NewLC(); + textDef->AppendL(TContactTextDefItem(KUidContactFieldFamilyName)); + CDesCArray* desArray = new(ELeave) CDesCArrayFlat(5); + desArray->AppendL(_L("e")); + + CContactIdArray* arr = NULL; + TRAP(err,arr = TestFindInTextDefL(aDb,*desArray,textDef, callBack, test) ); + +// test(err==KErrLocked); + desArray->Delete(0); + delete desArray; +//FIX + delete arr; + CleanupStack::PopAndDestroy(textDef); + + test.Next(_L("Test FindInTextDefL2")); + + TCallBack callBack2(findWordSplitterL); + CContactTextDef* textDef2=CContactTextDef::NewLC(); + textDef2->AppendL(TContactTextDefItem(KUidContactFieldFamilyName)); + textDef2->AppendL(TContactTextDefItem(KUidContactFieldUrl)); + CDesCArray* desArray2 = new(ELeave) CDesCArrayFlat(5); + desArray2->AppendL(_L("e")); + + TRAP(err,arr = TestFindInTextDefL(aDb,*desArray2,textDef2, callBack2, test) ); +// test(err==KErrLocked); + desArray2->Delete(0); + delete desArray2; +//FIX + delete arr; + CleanupStack::PopAndDestroy(textDef2); + } + + +/** + * Test ICC contacts can be matched using MatchPhoneNumberL API. The + * synchroniser is not called to validate the IDs at for this method because + * phone number resolution needs to be as quick as possible. + * Instead, validation is done when the client attempts to read the items. + * @param aDb Contact database + */ + + +void TestPhoneMatchingL(CContactDatabase& aDb) + { + test.Next(_L("Test phone match")); + + CContactIdArray* array = aDb.MatchPhoneNumberL(KTelephoneNum,KMaxPhoneMatchLength); + test(array->Count() == 4); + delete array; + + syncChecker->SetValidateResponseL(MContactSynchroniser::ERead,KErrNone); + syncChecker->SetValidateResponseL(MContactSynchroniser::EEdit, KErrNone); + syncChecker->SetValidateWriteResponseL(KErrNone); + aDb.SetDbViewContactType(KUidContactICCEntry); + TContactItemId id = (*aDb.SortedItemsL())[0]; + CContactItem* item = aDb.OpenContactLX(id); + CleanupStack::PushL(item); + CContactItemFieldSet& fieldset = item->CardFields(); + const TInt pos = fieldset.Find(KUidContactFieldPhoneNumber); + CContactItemField& field = fieldset[pos]; + CContactTextField* textfield = field.TextStorage(); + textfield->SetTextL(KTelephoneNumModified); + aDb.CommitContactL(*item); + CleanupStack::PopAndDestroy(2); //item, lock record + + CContactIdArray* array2 = aDb.MatchPhoneNumberL(KTelephoneNumModified,KMaxPhoneMatchLength); + test(array2->Count() == 1); + delete array2; + } + + +/** + * Test database iteration using TContactIter. + * @param aDb Contact database + */ + + +void TestDatabaseIterationL(CContactDatabase& aDb) + { + test.Next(_L("Test database iteration")); + + aDb.SetDbViewContactType(KUidContactICCEntry); + TContactIter iterator(aDb); + TContactItemId id = iterator.FirstL(); + while (id!=KNullContactId) + { + CContactItem* item = aDb.ReadContactLC(id); + test(item->Type() == KUidContactICCEntry); + CleanupStack::PopAndDestroy(item); + id = iterator.NextL(); + } + } + + + +CContactItem* ReadItemL( CContactDatabase& aDatabase, TContactItemId aId ) + { + CContactItem* retval = NULL; + retval = aDatabase.ReadMinimalContactLC( aId ); + CleanupStack::Pop( retval ); + return retval; + } + +/** + * Verify that the plug-in implementation is called when the + * ReadMinimalContactL API is used. + * + * Tests methods: + * IMPORT_C CContactItem* ReadMinimalContactL(TContactItemId aContactId); + * IMPORT_C CContactItem* ReadMinimalContactLC(TContactItemId aContactId); + * + * @param aDb Contact database + * @param aId Contact item ID to read + */ +void TestReadMinimalContactL(CContactDatabase& aDb, TContactItemId aId) + { + syncChecker->SetValidateResponseL(MContactSynchroniser::ERead,KErrNone); + syncChecker->ResetMethodCallCountsL(); + test(syncChecker->ValidateMethodCallCountL() == 0); + CContactItem* item = aDb.ReadMinimalContactLC(aId); + test(syncChecker->ValidateMethodCallCountL() == 1); + CleanupStack::PopAndDestroy(item); + + syncChecker->SetValidateResponseL(MContactSynchroniser::ERead,KErrAccessDenied); + syncChecker->ResetMethodCallCountsL(); + test(syncChecker->ValidateMethodCallCountL() == 0); + item=NULL; + //TRAPD(err, item = aDb.ReadMinimalContactLC(aId)); + TRAPD( err, item = ReadItemL( aDb, aId ) ); + delete item; + test(err==KErrAccessDenied); + test(syncChecker->ValidateMethodCallCountL() == 1); + } + +/** + * Verify that the plug-in implementation is called when the + * ReadContactL API is used. + * + * Tests code called by methods: + * IMPORT_C CContactItem* ReadContactL(TContactItemId aContactId); + * IMPORT_C CArrayPtr* ReadContactAndAgentL(TContactItemId aContactId); + * IMPORT_C CContactItem* ReadContactL(TContactItemId aContactId,const CContactItemViewDef& aViewDef); + * IMPORT_C CContactItem* ReadContactLC(TContactItemId aContactId); + * IMPORT_C CContactItem* ReadContactLC(TContactItemId aContactId,const CContactItemViewDef& aViewDef); + * + * @param aDb Contact database + * @param aId Contact item ID to read + */ +void TestReadContactL(CContactDatabase& aDb, TContactItemId aId) + { + syncChecker->SetValidateResponseL(MContactSynchroniser::ERead,KErrNone); + syncChecker->ResetMethodCallCountsL(); + test(syncChecker->ValidateMethodCallCountL() == 0); + CContactItem* item = aDb.ReadContactLC(aId); + test(syncChecker->ValidateMethodCallCountL() == 1); + CleanupStack::PopAndDestroy(item); + + syncChecker->SetValidateResponseL(MContactSynchroniser::ERead,KErrAccessDenied); + syncChecker->ResetMethodCallCountsL(); + test(syncChecker->ValidateMethodCallCountL() == 0); + item=NULL; + TRAPD(err, item = aDb.ReadContactL(aId)); + delete item; + test(err==KErrAccessDenied); + test(syncChecker->ValidateMethodCallCountL() == 1); + } + +/** + * Verify that read validation is done for ReadContactTextDefL + * + * @param aDb Contact database + * @param aId Contact item ID to read + */ +void TestReadTextDefinitionL(CContactDatabase& aDb, TContactItemId aId) + { + syncChecker->SetValidateResponseL(MContactSynchroniser::ERead,KErrNone); + syncChecker->ResetMethodCallCountsL(); + test(syncChecker->ValidateMethodCallCountL() == 0); + TBuf<64> textDef; + aDb.ReadContactTextDefL(aId,textDef); + test(syncChecker->ValidateMethodCallCountL() == 1); + + syncChecker->SetValidateResponseL(MContactSynchroniser::ERead,KErrAccessDenied); + syncChecker->ResetMethodCallCountsL(); + test(syncChecker->ValidateMethodCallCountL() == 0); + TRAPD(err, aDb.ReadContactTextDefL(aId,textDef)); + test(err==KErrAccessDenied); + test(syncChecker->ValidateMethodCallCountL() == 1); + } + +/** + * Create example ICC Entry + * @param aDb Contact database + */ +TContactItemId CreateTestICCEntryL(CContactDatabase& aDb) + { + TContactItemId templateId = aDb.ICCTemplateIdL(KUidIccGlobalAdnPhonebook); + CContactItem* iccTemplate = aDb.ReadContactLC(templateId); + CContactICCEntry* entry = CContactICCEntry::NewL(*iccTemplate); + CleanupStack::PopAndDestroy(iccTemplate); + CleanupStack::PushL(entry); + SetNameL(*entry,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,KGivenName,EFalse); + SetNameL(*entry,KUidContactFieldPhoneNumber,KUidContactFieldVCardMapTEL,KTelephoneNum,EFalse); + + //Add to database + syncChecker->SetValidateWriteResponseL(KErrNone); + syncChecker->SetValidateResponseL(MContactSynchroniser::ERead,KErrNone); + syncChecker->SetDeleteContactResponseL(KErrNone); + + TContactItemId id = aDb.AddNewContactL(*entry); + + CleanupStack::PopAndDestroy(entry); + test(id!=KNullContactId); + return id; + } + +/** + * Verify Read validation is being done for reading items. + * @param aDb Contact database + */ + +void TestReadL(CContactDatabase& aDb) + { + TContactItemId id = CreateTestICCEntryL(aDb); + test.Next(_L("TestReadMinimalContactL")); + + TestReadMinimalContactL(aDb,id); + test.Next(_L("TestReadContactL")); + + TestReadContactL(aDb,id); + test.Next(_L("TestReadTextDefinitionL")); + + TestReadTextDefinitionL(aDb,id); + } + +/** + * Verify that edit validation is being done for ICC entries + * and write validation is done when Commit is called. + * @param aDb Contact database + * @param aId Item Id to edit + */ +void TestSuccessfulEditL(CContactDatabase& aDb, TContactItemId aId) + { + syncChecker->SetValidateResponseL(MContactSynchroniser::ERead,KErrNone); + syncChecker->SetValidateResponseL(MContactSynchroniser::EEdit, KErrNone); + syncChecker->SetValidateWriteResponseL(KErrNone); + syncChecker->ResetMethodCallCountsL(); + test(syncChecker->ValidateMethodCallCountL() == 0); + CContactItem* item = aDb.OpenContactLX(aId); + CleanupStack::PushL(item); + test(syncChecker->ValidateMethodCallCountL() == 2); + + CContactItemFieldSet& fieldset = item->CardFields(); + const TInt pos = fieldset.Find(KUidContactFieldFamilyName); + CContactItemField& field = fieldset[pos]; + CContactTextField* textfield = field.TextStorage(); + textfield->SetTextL(KGivenEditName); + + aDb.CommitContactL(*item); + test(syncChecker->ValidateMethodCallCountL() == 4); + CleanupStack::PopAndDestroy(2); //item, lock record + } + +/** + * Unsuccessful edit. Fail the edit validation request + * @param aDb Contact database + * @param aId Item Id to edit + */ +void FailEditValidationL(CContactDatabase& aDb, TContactItemId aId) + { + syncChecker->SetValidateResponseL(MContactSynchroniser::ERead,KErrNone); + syncChecker->SetValidateResponseL(MContactSynchroniser::EEdit, KErrAccessDenied); + syncChecker->ResetMethodCallCountsL(); + test(syncChecker->ValidateMethodCallCountL() == 0); + TRAPD(err, aDb.OpenContactL(aId)); + test(syncChecker->ValidateMethodCallCountL() == 2); + test(err==KErrAccessDenied); + } + +/** + * Unsuccessful edit. Fail the write validation request + * @param aDb Contact database + * @param aId Item Id to edit + */ +void FailWriteValidationL(CContactDatabase& aDb, TContactItemId aId) + { + syncChecker->SetValidateResponseL(MContactSynchroniser::ERead,KErrNone); + syncChecker->SetValidateResponseL(MContactSynchroniser::EEdit, KErrNone); + syncChecker->SetValidateWriteResponseL(KErrAccessDenied); + syncChecker->ResetMethodCallCountsL(); + + CContactItem* item = aDb.OpenContactLX(aId); + CleanupStack::PushL(item); + CContactItemFieldSet& fieldset = item->CardFields(); + const TInt pos = fieldset.Find(KUidContactFieldFamilyName); + CContactItemField& field = fieldset[pos]; + CContactTextField* textfield = field.TextStorage(); + textfield->SetTextL(KGivenEditName); + + TRAPD(err, aDb.CommitContactL(*item)); + test(syncChecker->ValidateMethodCallCountL() == 4); + test(err==KErrAccessDenied); + + CleanupStack::PopAndDestroy(2); //item, lock record + } + +/** + * Verify that edit validation is being done for ICC entries + * and write validation is done when Commit is called. + * @param aDb Contact database + */ + +void TestEditL(CContactDatabase& aDb) + { + TContactItemId id = CreateTestICCEntryL(aDb); + test.Next(_L("Test successful edit")); + + TestSuccessfulEditL(aDb,id); + test.Next(_L("Test unsuccessful edit - fail edit")); + + FailEditValidationL(aDb,id); + test.Next(_L("Test unsuccessful edit - fail write")); + + FailWriteValidationL(aDb,id); + } + +/** + * Test an unsuccessful delete + * @param aDb Contact database + */ +void TestUnsuccessfulDeleteL(CContactDatabase& aDb) + { + syncChecker->SetValidateResponseL(MContactSynchroniser::ERead,KErrNone); + syncChecker->SetValidateResponseL(MContactSynchroniser::EEdit, KErrNone); + TContactItemId id = CreateTestICCEntryL(aDb); + // Creating the contact sets the delete error to KErrNone, so must do this afterwards + syncChecker->SetDeleteContactResponseL(KErrCorrupt); + syncChecker->ResetMethodCallCountsL(); + TRAPD(err, aDb.DeleteContactL(id)); + test(syncChecker->ValidateMethodCallCountL() == 2); + test(err==KErrCorrupt); + //Read contact to check it wasn't deleted anyway + CContactItem* item = NULL; + TRAP(err,item = aDb.ReadContactL(id)); + test(err==KErrNone); + delete item; + } + + +/** + * Verify that delete validation is being done for ICC entries. + * @param aDb Contact database + */ + +void TestDeleteL(CContactDatabase& aDb) + { + test.Next(_L("Test successful delete")); + + TContactItemId id = CreateTestICCEntryL(aDb); + syncChecker->ResetMethodCallCountsL(); + aDb.DeleteContactL(id); + test(syncChecker->ValidateMethodCallCountL() == 2); + test.Next(_L("Test unsuccessful delete")); + + TestUnsuccessfulDeleteL(aDb); + } + + +/** + * Create template card for ICC contact items + * @param aDb Contact database + */ +TContactItemId CreateICCTemplateL(CContactDatabase& aDb) + { + CContactItem* temp = aDb.CreateContactCardTemplateLC(KTemplateName); + TContactItemId templateId = temp->Id(); + CleanupStack::PopAndDestroy(temp); + temp=NULL; + + //Remove all the unnecessary fields + temp = aDb.OpenContactLX(templateId); + CleanupStack::PushL(temp); + const TInt fieldCount = temp->CardFields().Count(); + for(TInt i=fieldCount-1;i>=0;i--) + temp->RemoveField(i); + + CContactItemField* name = CContactItemField::NewLC(KStorageTypeText,KUidContactFieldFamilyName); + name->SetMapping(KUidContactFieldVCardMapUnusedN); + temp->AddFieldL(*name); + CleanupStack::Pop(name); + + CContactItemField* number = CContactItemField::NewLC(KStorageTypeText,KUidContactFieldPhoneNumber); + number->SetMapping(KUidContactFieldVCardMapTEL); + temp->AddFieldL(*number); + CleanupStack::Pop(number); + + CContactItemField* slotnum = CContactItemField::NewLC(KStorageTypeText,KUidContactFieldICCSlot); + temp->AddFieldL(*slotnum); + CleanupStack::Pop(slotnum); + + CContactItemField* phonebook = CContactItemField::NewLC(KStorageTypeText,KUidContactFieldICCPhonebook); + temp->AddFieldL(*phonebook); + CleanupStack::Pop(phonebook); + + aDb.CommitContactL(*temp); + CleanupStack::PopAndDestroy(2); // temp, close template + + return templateId; + } + +/** + * Test SetDbViewContactType can be used for KUidContactICCEntry items. + * @param aDb Contact database + */ +void TestDatabaseViewL(CContactDatabase& aDb) + { + syncChecker->SetValidateResponseL(MContactSynchroniser::ERead,KErrNone); + syncChecker->SetValidateWriteResponseL(KErrNone); + CntTest->CloseDatabase(); + CntTest->DeleteDatabaseL(); + // re-initialise the TLS + syncChecker->EnableVerboseLoggingL(); + + CntTest->CreateDatabaseL(); + CntTest->OpenDatabaseL(); + delete synchroniser; + synchroniser = CContactTestSynchroniser::NewL(); + // test with GSM ADN phonebook only + //test(KErrNone == syncChecker->SetGsmPhonebook()); + + // Start from clean + CContactItem* card = CContactCard::NewLC(); + aDb.AddNewContactL(*card); + aDb.CreateContactGroupLC(); + aDb.CreateOwnCardLC(); + TContactItemId id=CreateICCTemplateL(aDb); + test(KErrNone == syncChecker->UpdatePhonebookEntryL(KUidIccGlobalAdnPhonebook, id, KNullContactId)); + TContactItemId templateId = aDb.ICCTemplateIdL(KUidIccGlobalAdnPhonebook); + CContactItem* iccTemplate = aDb.ReadContactLC(templateId); + CContactICCEntry* iccentry = CContactICCEntry::NewL(*iccTemplate); + CleanupStack::PopAndDestroy(iccTemplate); + CleanupStack::PushL(iccentry); + aDb.AddNewContactL(*iccentry); + TContactItemId iccId = iccentry->Id(); + CleanupStack::PopAndDestroy(4); //card,group,owncard,iccentry + + test(aDb.SortedItemsL()->Count() == 5); //default view includes ALL contact types + CntTest->CloseDatabase(); + delete synchroniser; + synchroniser = NULL; + CntTest->OpenDatabaseL(); + aDb.SetDbViewContactType(KUidContactICCEntry); + test(aDb.SortedItemsL()->Count() == 1); + test((*aDb.SortedItemsL())[0]==iccId); + } + +/** + * Create phonebook group + * @param aDb Contact database + */ +TContactItemId CreatePhonebookGroupL(CContactDatabase& aDb) + { + _LIT(KPhbkGroup,"ADN Phonebook"); + CContactItem* group = aDb.CreateContactGroupLC(KPhbkGroup); + TContactItemId groupId = group->Id(); + CleanupStack::PopAndDestroy(group); + return groupId; + } + +/** + * Verify that the template was correctly added + * @param aTemplate CContactCardTemplate template item + */ +void CheckTemplateL(CContactItem& aTemplate) + { + test(aTemplate.Type() == KUidContactCardTemplate); + test(aTemplate.TemplateRefId() == KNullContactId); + test(static_cast(aTemplate).GetTemplateLabelL() == KTemplateName); + CContactItemFieldSet& fieldset = aTemplate.CardFields(); + TInt pos = fieldset.Find(KUidContactFieldTemplateLabel); + test(pos!=KErrNotFound); + TInt count = fieldset.Count(); + test(count==5); //label, name, number, ICC slot, phonebook + } + + +/** + * Check that the field of type aFieldType has the same content as + * aExpectedContent + * @param aFieldset Contact item fieldset + * @param aFieldType Field type to test + * @param aExpectedContent Expected data + */ +void CheckFieldContentL(CContactItemFieldSet& aFieldset, TFieldType aFieldType, const TDesC& aExpectedContent) + { + TInt pos = aFieldset.Find(aFieldType); + CContactItemField& field = aFieldset[pos]; + CContactTextField* textField = field.TextStorage(); + test(textField != NULL); + test(textField->Text() == aExpectedContent); + } + +/** + * Test creation of CContactICCEntry items. + * + * Set-up appropriate template and group ready... + * @param aDb Contact database + */ + +/** + +@SYMTestCaseID PIM-T-ICCENTRY-0001 + +*/ + +void TestCreationL(CContactDatabase& aDb) + { + _LIT(KTestCreation,"@SYMTESTCaseID:PIM-T-ICCENTRY-0001 Create CContactICCEntry item"); + test.Start(KTestCreation); + + //System Template + TContactItemId systemTemplateId = aDb.TemplateId(); + CContactItem* systemTemplate = aDb.ReadContactLC(systemTemplateId); + CContactICCEntry* entry = CContactICCEntry::NewL(*systemTemplate); + CleanupStack::PopAndDestroy(systemTemplate); + CleanupStack::PushL(entry); + + //Test CContactICCEntry items can be identified from normal contact cards + test(entry->Type() == KUidContactICCEntry); + test(entry->TemplateRefId() == systemTemplateId); + CleanupStack::PopAndDestroy(entry); + + //Create user defined template for ICC contacts + test.Next(_L("CContactDatabase::ICCTemplateL()")); + + TContactItemId templateId = CreateICCTemplateL(aDb); + test(KErrNone == syncChecker->UpdatePhonebookEntryL(KUidIccGlobalAdnPhonebook, templateId, KNullContactId)); + + //Check that contacts model calls the plug-in when asked for the + //template ID. + TInt callCount = syncChecker->ValidateMethodCallCountL(); + test(callCount==0); + TContactItemId templateIdFromCntmodel; + templateIdFromCntmodel = aDb.ICCTemplateIdL(KUidIccGlobalAdnPhonebook); + + test(syncChecker->ValidateMethodCallCountL() == 1); + test(templateId == templateIdFromCntmodel); + + CContactItem* iccTemplate = aDb.ReadContactLC(templateId); + CheckTemplateL(*iccTemplate); + //create ICC contact + CContactICCEntry* iccentry = CContactICCEntry::NewL(*iccTemplate); + CleanupStack::PopAndDestroy(iccTemplate); + CleanupStack::PushL(iccentry); + test(iccentry->Type() == KUidContactICCEntry); + test(iccentry->TemplateRefId() == templateId); + CleanupStack::PopAndDestroy(iccentry); + + test.End(); + } + + + +/** + * Test successful addition to database. + * @param aDb Contact database + */ +void TestSuccessfulAddL(CContactDatabase& aDb) + { + //Create group + TContactItemId groupId = CreatePhonebookGroupL(aDb); + test(KErrNone == syncChecker->UpdatePhonebookGroupIdL(KUidIccGlobalAdnPhonebook, groupId)); + //Create item and add fields + TContactItemId templateId = aDb.ICCTemplateIdL(KUidIccGlobalAdnPhonebook); + CContactItem* iccTemplate = aDb.ReadContactLC(templateId); + CContactICCEntry* entry = CContactICCEntry::NewL(*iccTemplate); + CleanupStack::PopAndDestroy(iccTemplate); + CleanupStack::PushL(entry); + SetNameL(*entry,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,KGivenName,EFalse); + SetNameL(*entry,KUidContactFieldPhoneNumber,KUidContactFieldVCardMapTEL,KTelephoneNum,EFalse); + + //Add to database + syncChecker->ResetMethodCallCountsL(); + syncChecker->SetValidateWriteResponseL(KErrNone); + syncChecker->SetValidateResponseL(MContactSynchroniser::ERead,KErrNone); + + test(syncChecker->ValidateMethodCallCountL() == 0); + TContactItemId id = aDb.AddNewContactL(*entry); + CleanupStack::PopAndDestroy(entry); + test(syncChecker->ValidateMethodCallCountL() == 3); + test(id!=KNullContactId); + + CContactICCEntry* fetchedItem = static_cast(aDb.ReadContactL(id)); + CleanupStack::PushL(fetchedItem); + //Check group membership + const CContactIdArray* owned = fetchedItem->GroupsJoined(); + test(owned!=NULL && owned->Count() == 1); + test((*owned)[0]==groupId); + + //Check number of fields and content + + CContactItemFieldSet& fieldset = fetchedItem->CardFields(); + TInt pos = fieldset.Find(KUidContactFieldTemplateLabel); + test(pos==KErrNotFound); + +// test(fieldset.Count() == 3); + +/* for (TInt i=0; iResetMethodCallCountsL(); + syncChecker->SetValidateWriteResponseL(KErrAccessDenied); + TRAPD(error, aDb.AddNewContactL(*entry)); + test(error==KErrAccessDenied); + test(syncChecker->ValidateMethodCallCountL() == 1); + CleanupStack::PopAndDestroy(entry); + } + +/** + * Test addition to database without adding to a group + * @param aDb Contact database + */ +void TestAddingWithoutGroupL(CContactDatabase& aDb) + { + TContactItemId templateId = aDb.ICCTemplateIdL(KUidIccGlobalAdnPhonebook); + CContactItem* iccTemplate = aDb.ReadContactLC(templateId); + CContactICCEntry* entry = CContactICCEntry::NewL(*iccTemplate); + CleanupStack::PopAndDestroy(iccTemplate); + CleanupStack::PushL(entry); + SetNameL(*entry,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,KGivenName,EFalse); + SetNameL(*entry,KUidContactFieldPhoneNumber,KUidContactFieldVCardMapTEL,KTelephoneNum,EFalse); + + syncChecker->ResetMethodCallCountsL(); + syncChecker->SetValidateWriteResponseL(KErrNone); + TInt oldGroupId = syncChecker->GroupIdL(KUidIccGlobalAdnPhonebook); + test(KErrNone == syncChecker->UpdatePhonebookGroupIdL(KUidIccGlobalAdnPhonebook, KNullContactId)); + TContactItemId id = aDb.AddNewContactL(*entry); + test(syncChecker->ValidateMethodCallCountL() == 3); + CleanupStack::PopAndDestroy(entry); + + CContactICCEntry* fetchedItem = static_cast(aDb.ReadContactL(id)); + CleanupStack::PushL(fetchedItem); + //Check group membership + const CContactIdArray* owned = fetchedItem->GroupsJoined(); + test(owned==NULL || owned->Count() == 0); + CleanupStack::PopAndDestroy(fetchedItem); + + test(KErrNone == syncChecker->UpdatePhonebookGroupIdL(KUidIccGlobalAdnPhonebook, oldGroupId)); + } + +/** + * Verify that adding contact cards doesn't call the synchroniser interface + * @param aDb Contact database + */ +void TestAddingContactCardL(CContactDatabase& aDb) + { + CContactCard* card = CContactCard::NewLC(); + syncChecker->ResetMethodCallCountsL(); + aDb.AddNewContactL(*card); + test(syncChecker->ValidateMethodCallCountL() == 0); + CleanupStack::PopAndDestroy(card); + } + +/** + * Test addition of CContactICCEntry items. + * @param aDb Contact database + */ +void TestAddL(CContactDatabase& aDb) + { + TestCreationL(aDb); + TestSuccessfulAddL(aDb); + TestUnsuccessfulAddL(aDb); + TestAddingWithoutGroupL(aDb); + TestAddingContactCardL(aDb); + } + +/** + * Test PhonebookGroupIdL method. + * @param aDb Contact database + */ +void TestPhonebookGroupIdL(CContactDatabase& aDb) + { + synchroniser = CContactTestSynchroniser::NewL(); + const TContactItemId expectedGroupId(KNullContactId); + test(KErrNone == syncChecker->UpdatePhonebookGroupIdL(KUidIccGlobalAdnPhonebook, expectedGroupId)); + TContactItemId id = aDb.PhonebookGroupIdL(); + test(id == expectedGroupId); + } + + +void CheckForPhbkSyncPluginL() + { + test.Next(_L("Check for PhbkSync test plug-in")); + + + RImplInfoPtrArray implInfoArray; + CleanupResetAndDestroyPushL(implInfoArray); + REComSession::ListImplementationsL(KUidEcomCntPhBkSyncInterface, implInfoArray); + //Find implementations of KUidEcomCntPhBkSyncInterface + TInt availCount = implInfoArray.Count(); + TInt count; + for(count = 0; count < availCount; count++) + { + //const TUid firstImplementationFound = implInfoArray[count]->ImplementationUid(); + CImplementationInformation *info = implInfoArray[count]; + test.Printf(_L("\n")); + test.Printf(_L("PhbkSync plugin #%i, Implementation UID 0x%08X version %i\n"), + count + 1, info->ImplementationUid(), info->Version()); + test.Printf(_L("Plugin name = \"%S\"\n"), &(info->DisplayName())); + } + + // is telephony's plug-in in the list? + for(count = 0; count < availCount; count++) + { + //const TUid firstImplementationFound = implInfoArray[count]->ImplementationUid(); + CImplementationInformation *info = implInfoArray[count]; + if(info->DisplayName() == KTestPluginName) + { + test.Printf(_L("\n")); + test.Printf(_L("This test has now loaded the test plugin")); + test.Printf(_L("\n")); + availCount = 1; + break; + } + + if(info->DisplayName() == KPluginName) + { + test.Printf(_L("\n")); + test.Printf(_L("This test only works with Contacts the test plugin and not the original phonebooksync plugin.")); + test.Printf(_L("Depending on the build to removed the plugin in different ways:")); + test.Printf(_L("hardware - delete the line \"ECOM_PLUGIN(phbksyncplugin.dll,1020428C.rsc)\" from phbksync.iby")); + test.Printf(_L("winscw - delete phbksyncplugin.dll from %epocroot%/epoc32/release/winscw/udeb or similarly named directory")); + test.Printf(_L("\n")); + test(0); // stop + break; + } + } + + // only continue test if there is exactly one plug-in present + test(availCount == 1); + CleanupStack::PopAndDestroy(&implInfoArray); + } + +/** Lists tests to execute */ + +void DoTestsL() + { + test.Start(_L("Basic tests for CContactICCEntry")); + + + CheckForPhbkSyncPluginL(); + + CntTest->CreateDatabaseL(); + CntTest->OpenDatabaseL(); + + syncChecker = CContactSyncChecker::NewL(); + synchroniser = CContactTestSynchroniser::NewL(); + syncChecker->ResetL(); + syncChecker->EnableVerboseLoggingL(); + // test with GSM ADN phonebook only + test(KErrNone == syncChecker->SetGsmPhonebookL()); + + CContactDatabase& db= *CntTest->Db(); + TestAddL(db); + TestReadL(db); + TestEditL(db); + TestPhoneMatchingL(db); + TestFindingL(db); + TestDeleteL(db); + TestDatabaseIterationL(db); + TestDatabaseViewL(db); + TestPhonebookGroupIdL(db); + + CntTest->CloseDatabase(); + CntTest->DeleteDatabaseL(); + + delete synchroniser; + synchroniser = NULL; + delete syncChecker; + syncChecker = NULL; + } + +/** Standard E32Main method */ +GLDEF_C TInt E32Main() + { + __UHEAP_MARK; + CntTest=new(ELeave) CCntTest; + CntTest->ConstructL(test,KDatabaseFileName); + TRAPD(err,DoTestsL()); + if (err) + { + // delete globals + delete synchroniser; + synchroniser = NULL; + delete syncChecker; + syncChecker = NULL; + } + CntTest->EndTestLib(err); + __UHEAP_MARKEND; + return KErrNone; + }