// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
//
#include <e32test.h>
#include <f32file.h>
#include <s32file.h>
#include <cntdb.h>
#include <cntitem.h>
#include <cntfield.h>
#include <cntfldst.h>
#include <bautils.h>
#include <barsc.h>
#include <barsread.h>
#include <cntmodel.rsg>
#include "T_UTILS.H"
CCntTest* CntTest=NULL;
LOCAL_D RTest test(_L("T_TEMPL"));
const TPtrC KDatabaseFileName=_L("C:T_TEMPL");
const TInt KTotalFindRecords=20;
#define KCardGivenName _L("Given Name #%d")
#define KCardFamilyName _L("Family Name #%d")
#define KCardFieldText _L("Card id %d, text field #%d")
#define KCardFieldEditedText _L("UPDATED Card id %d, text field #%d")
LOCAL_C void CreateDatabaseL()
//
// Create a database in a store and add some contact cards
//
{
CContactDatabase *db=CntTest->CreateDatabaseL();
test.Next(_L("Add basic cards"));
CContactCard* card=CContactCard::NewL();
CleanupStack::PushL(card);
for (TInt ii=0;ii<20;ii++)
{
db->AddNewContactL(*card);
}
CleanupStack::PopAndDestroy(); // card
CntTest->CloseDatabase();
}
LOCAL_C void AddFieldL(CContactItem *aItem,TFieldType aFieldType, const TDesC &aLabel, const TDesC &aFieldText)
{
CContactItemField* field=CContactItemField::NewLC(KStorageTypeText,aFieldType);
field->SetLabelL(aLabel);
aItem->AddFieldL(*field);
if (aFieldText.Length()>0)
field->TextStorage()->SetTextL(aFieldText);
CleanupStack::Pop(); // field
}
LOCAL_C void AddDateFieldL(CContactItem *aItem,TFieldType aFieldType, const TDesC &aLabel, TDateTime *aDateTime)
{
CContactItemField* field=CContactItemField::NewLC(KStorageTypeDateTime,aFieldType);
field->SetLabelL(aLabel);
aItem->AddFieldL(*field);
if (aDateTime)
field->DateTimeStorage()->SetTime(*aDateTime);
CleanupStack::Pop(); // field
}
LOCAL_C CContactItem* ReadContactIncHiddenFieldsLC(CContactDatabase* aDb, TContactItemId aContactId)
{
CContactItemViewDef *viewDef=CContactItemViewDef::NewLC(CContactItemViewDef::EMaskFields,CContactItemViewDef::EIncludeHiddenFields);
CContactItem *contact=aDb->ReadContactL(aContactId,*viewDef);
CleanupStack::PopAndDestroy(); // viewDef
CleanupStack::PushL(contact);
return(contact);
}
LOCAL_C void doTestTemplate(CContactDatabase* aDb, TContactItemId aTemplateId,CContactTemplate* aContactTemplate, TBool aTemplateLabelRemoved)
{
CContactItem *checkTemplate=ReadContactIncHiddenFieldsLC(aDb,aTemplateId);
test(CompareItemFields(aContactTemplate,checkTemplate));
CleanupStack::PopAndDestroy(); // checkTemplate
//
CContactCard *copy=CContactCard::NewLC(aContactTemplate);
// fails due to template lable being removed. // test code needs fixing
test(CompareItemFields(aContactTemplate,copy,EFalse,aTemplateLabelRemoved));
CleanupStack::PopAndDestroy(); // copy
}
LOCAL_C void CheckDefaultTemplate(CContactDatabase* aDb, RFs& aFs, TContactItemId aSystemTemplateId)
{
test.Next(_L("System template"));
_LIT(KCntSystemTemplate,"z:\\resource\\cntmodel\\cntmodel.rsc");
TFileName fileName(KCntSystemTemplate);
BaflUtils::NearestLanguageFile(aFs,fileName);
//
RResourceFile resourceFile;
resourceFile.OpenL(CntTest->Fs(),fileName);
CleanupClosePushL(resourceFile);
resourceFile.ConfirmSignatureL(4);
TResourceReader resReader;
resReader.SetBuffer(resourceFile.AllocReadLC(R_CNTUI_NEW_FIELD_DEFNS));
//
CContactTemplate *testTemplate=CContactTemplate::NewLC();
TInt count=resReader.ReadInt16(); // num fields
while(count--)
{
TStorageType storageType=resReader.ReadInt32();
TUid contactFieldUid=TUid::Uid(resReader.ReadInt32());
TUid vCardMappingUid=TUid::Uid(resReader.ReadInt32());
//
CContactItemField* field=CContactItemField::NewLC(storageType);
//
field->SetMapping(vCardMappingUid);
if (contactFieldUid!=KUidContactFieldNone)
field->AddFieldTypeL(contactFieldUid);
//
TInt mappingCount;
if((mappingCount=resReader.ReadInt16())!=0)
{
while(mappingCount--)
field->AddFieldTypeL(TUid::Uid(resReader.ReadInt32()));
}
field->SetUserFlags(resReader.ReadInt32());
field->SetLabel(resReader.ReadHBufCL());
TUint flags=resReader.ReadInt32();
if (flags&EContactFieldFlagHidden)
field->SetHidden(ETrue);
if (flags&EContactFieldFlagReadOnly)
field->SetReadOnly(ETrue);
if (flags&EContactFieldFlagSynchronize)
field->SetSynchronize(ETrue);
if (flags&EContactFieldFlagDisabled)
field->SetDisabled(ETrue);
//
testTemplate->AddFieldL(*field);
CleanupStack::Pop();
}
doTestTemplate(aDb,aSystemTemplateId,testTemplate,ETrue);
CleanupStack::PopAndDestroy(3); // testTemplate,resourceFile close, resBuffer
}
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(); // item
}
}
LOCAL_C void AddFindRecordsL(CContactDatabase* aDb)
{
CContactItem* systemTemplate=ReadContactIncHiddenFieldsLC(aDb,aDb->TemplateId());
for (TInt ii=0;ii<KTotalFindRecords;ii++)
{
CContactItem* item=CContactCard::NewLC(systemTemplate);
TBuf<16> name;
if (ii%2)
{
name.Format(_L("Bates %d"),ii);
SetNameL(*item,KUidContactFieldJobTitle,name,EFalse);
//SetNameL(*item,KUidContactFieldFamilyName,name,EFalse);
SetNameL(*item,KUidContactFieldGivenName,_L("Norman"),EFalse);
}
else
{
name.Format(_L("Sod %d"),ii);
SetNameL(*item,KUidContactFieldFamilyName,name,EFalse);
SetNameL(*item,KUidContactFieldGivenName,_L("Silly"),EFalse);
}
if (ii%3)
{
CContactItemField* field=CContactItemField::NewLC(KStorageTypeDateTime,KUidContactFieldBirthday);
field->DateTimeStorage()->SetTime(TDateTime(1990+ii,(TMonth)(ii%12),(ii*3)%28,1,2,3,4));
item->AddFieldL(*field);
CleanupStack::Pop(); // field
}
aDb->AddNewContactL(*item);
CleanupStack::PopAndDestroy(); // item
}
CleanupStack::PopAndDestroy(); // systemTemplate
}
LOCAL_C void TestSystemTemplateL()
{
CContactDatabase* db=CntTest->OpenDatabaseL();
// add fields to cards to system template
CheckDefaultTemplate(db,CntTest->Fs(),db->TemplateId());
//
CContactTemplate *contactTemplate=(CContactTemplate *)db->OpenContactLX(db->TemplateId());
CleanupStack::PushL(contactTemplate);
AddFieldL(contactTemplate,TUid::Uid(1),_L("Uid1"),_L(""));
AddFieldL(contactTemplate,TUid::Uid(2),_L("Uid2"),_L(""));
AddFieldL(contactTemplate,TUid::Uid(3),_L("Uid3"),_L(""));
AddDateFieldL(contactTemplate,TUid::Uid(4),_L("Uid4"),NULL);
db->CommitContactL(*contactTemplate);
doTestTemplate(db,db->TemplateId(),contactTemplate,ETrue);
CleanupStack::PopAndDestroy(2); // contactTemplate,contactTemplate.Close()
//
AddFindRecordsL(db);
CContactItemFieldDef* fieldDef=new(ELeave) CContactItemFieldDef;
CleanupStack::PushL(fieldDef);
fieldDef->AppendL(KUidContactFieldJobTitle);
CContactIdArray* idarray=db->FindLC(_L("Bates 3"),fieldDef);
test(idarray->Count()==1);
//
// Now change the field KUidContactFieldFamilyName field type to Uid(44) and check
// the records field type also changes.
//
contactTemplate=(CContactTemplate *)db->OpenContactLX(db->TemplateId());
CleanupStack::PushL(contactTemplate);
CContactItemFieldSet& fieldSet=contactTemplate->CardFields();
TInt fieldNum=fieldSet.Find(KUidContactFieldJobTitle);
CContentType &ct=(CContentType&)fieldSet[fieldNum].ContentType();
ct.RemoveFieldType(KUidContactFieldJobTitle);
TUid newUidType=TUid::Uid(44);
ct.AddFieldTypeL(newUidType);
db->CommitContactL(*contactTemplate);
//
CContactItem *checkItem=(CContactTemplate *)db->ReadContactLC((*idarray)[0]);
CContactItemFieldSet& templateFieldSet=checkItem->CardFields();
test(templateFieldSet.Find(KUidContactFieldJobTitle)==KErrNotFound);
test(templateFieldSet.Find(newUidType)!=KErrNotFound);
CleanupStack::PopAndDestroy(1); // checkItem
//
// Check finding using the new field type also works
//
fieldDef->Delete(0);
fieldDef->AppendL(newUidType);
CContactIdArray* idarray2=db->FindLC(_L("Bates 3"),fieldDef);
test(idarray2->Count()==1);
test((*idarray2)[0]==(*idarray)[0]);
CleanupStack::PopAndDestroy(5); // fieldDef,idarray2,idarray,contactTemplate,contactTemplate.Close()
//
CntTest->CloseDatabase();
}
LOCAL_C void TestSystemTemplateRestorationL()
{
// Any field values present in the template are stripped out when the template is
// added to the database. However, it is still possible to store default values in
// a template if the template is first added, and then updated with default data present.
CContactDatabase* db=CntTest->OpenDatabaseL();
// create a new contact template
CContactItem* contactTemplate=db->CreateContactCardTemplateLC(_L("fieldDataNotRestoredTemplate"));
TContactItemId id=contactTemplate->Id();
CleanupStack::PopAndDestroy(contactTemplate);
// add some data to one of the template fields
CContactTemplate *openTemplate=(CContactTemplate *)db->OpenContactLX(id);
CleanupStack::PushL(openTemplate);
CContactItemFieldSet& fieldSet=openTemplate->CardFields();
TInt pos=fieldSet.Find(KUidContactFieldGivenName);
test(fieldSet[pos].TextStorage()->Text() == KNullDesC);
TBuf<12> givenName = _L("a given name");
SetNameL(*openTemplate,KUidContactFieldGivenName,givenName,EFalse);
// check the field value is set
CContactItemFieldSet& fieldSet2=openTemplate->CardFields();
pos=fieldSet2.Find(KUidContactFieldGivenName);
test(fieldSet2[pos].TextStorage()->Text() == givenName);
db->CommitContactL(*openTemplate);
CleanupStack::PopAndDestroy(2); // openTemplate, openTemplate.Close()
// the field value should still be set
CContactItem* contactTemplate2=db->ReadContactLC(id);
CContactItemFieldSet& fieldSet3=contactTemplate2->CardFields();
pos=fieldSet3.Find(KUidContactFieldGivenName);
test(fieldSet3[pos].TextStorage()->Text() == givenName);
CleanupStack::PopAndDestroy(contactTemplate2);
CntTest->CloseDatabase();
}
LOCAL_C void TestTemplateLabelsL()
{
CContactDatabase* db=CntTest->OpenDatabaseL();
//
CContactItem *contactTemplate=ReadContactIncHiddenFieldsLC(db,db->TemplateId());
CContactItem *card=CContactCard::NewLC(contactTemplate);
CContactItemFieldSet& fieldSet=card->CardFields();
fieldSet[0].TextStorage()->SetTextL(_L("Sum text"));
fieldSet[2].TextStorage()->SetTextL(_L("Some more text"));
TContactItemId id1=db->AddNewContactL(*card);
//
CContactItem *card2=ReadContactIncHiddenFieldsLC(db,id1);
test(CompareItemFields(contactTemplate,card2,EFalse,ETrue));
//
CContactItem *contactTemplate2=ReadContactIncHiddenFieldsLC(db,db->TemplateId());
CContactItem *card3=CContactCard::NewLC(contactTemplate2);
CContactItemFieldSet& fieldSet2=card3->CardFields();
fieldSet2[0].SetLabelL(_L("Label Zero"));
fieldSet2[0].TextStorage()->SetTextL(_L("x"));
fieldSet2[1].TextStorage()->SetTextL(_L("x"));
fieldSet2[2].SetLabelL(_L("Label Too"));
TContactItemId id2=db->AddNewContactL(*card3);
fieldSet2[1].SetLabelL(fieldSet[1].Label()); // Should be reset because SetLabelUnspecified is true
fieldSet2[2].SetLabelL(fieldSet[2].Label()); // Should be reset because field is empty
//
CContactItem *card4=ReadContactIncHiddenFieldsLC(db,id2);
test(CompareItemFields(card3,card4,EFalse));
CleanupStack::PopAndDestroy(3); // template2,card3,card4
CleanupStack::PopAndDestroy(3); // card,card2,template,template.Close()
//
CContactTemplate *openTemplate=(CContactTemplate *)db->OpenContactLX(db->TemplateId());
CleanupStack::PushL(openTemplate);
CContactItemFieldSet& templateFieldSet=openTemplate->CardFields();
templateFieldSet[1].SetDisabled(ETrue);
templateFieldSet[1].SetReadOnly(ETrue);
db->CommitContactL(*openTemplate);
CContactItem *card5=ReadContactIncHiddenFieldsLC(db,id1);
test(CompareItemFields(openTemplate,card5,EFalse,ETrue));
CleanupStack::PopAndDestroy(3); // card5, openTemplate, openTemplate.Close()
//
openTemplate=(CContactTemplate *)db->OpenContactLX(db->TemplateId());
CleanupStack::PushL(openTemplate);
openTemplate->CardFields()[1].SetReadOnly(EFalse);
openTemplate->CardFields()[1].SetDisabled(EFalse);
db->CommitContactL(*openTemplate);
CleanupStack::PopAndDestroy(2); // openTemplate, openTemplate.Close()
//
CntTest->CloseDatabase();
}
LOCAL_C CContactItemField *doAddFieldL(CContactItem *aItem,TFieldType aMapping,TInt aPos, const TDesC &aLabel,TFieldType *aFieldType1,TFieldType *aFieldType2,TFieldType *aFieldType3)
{
CContactItemField* field=CContactItemField::NewLC(KStorageTypeText);
field->SetMapping(aMapping);
field->SetLabelL(aLabel);
if (aFieldType1)
{
field->AddFieldTypeL(*aFieldType1);
if (aFieldType2)
{
field->AddFieldTypeL(*aFieldType2);
if (aFieldType3)
field->AddFieldTypeL(*aFieldType3);
}
}
if (aPos<0)
aItem->AddFieldL(*field);
else
aItem->InsertFieldL(*field,aPos);
CleanupStack::Pop(); // field
return(field);
}
LOCAL_C CContactItemField *InsertFieldL(CContactItem *aItem,TFieldType aMapping,TInt aPos,const TDesC &aLabel,TFieldType *aFieldType1=NULL,TFieldType *aFieldType2=NULL,TFieldType *aFieldType3=NULL)
{
return(doAddFieldL(aItem,aMapping,aPos,aLabel,aFieldType1,aFieldType2,aFieldType3));
}
LOCAL_C CContactItemField *AddFieldL(CContactItem *aItem,TFieldType aMapping,const TDesC &aLabel,TFieldType *aFieldType1=NULL,TFieldType *aFieldType2=NULL,TFieldType *aFieldType3=NULL)
{
return(doAddFieldL(aItem,aMapping,-1,aLabel,aFieldType1,aFieldType2,aFieldType3));
}
struct TTemplateMapTest
{
public:
inline TTemplateMapTest(TFieldType aMapping,TFieldType *aFieldType1,TFieldType *aFieldType2,TFieldType *aFieldType3, const TDesC &aFieldName, TInt aFieldNumber, TBool aExactContentMatch, TFieldType *aExtraField=NULL, TFieldType *aMissingField=NULL) :
iMapping(aMapping),iFieldType1(aFieldType1),iFieldType2(aFieldType2),iFieldType3(aFieldType3),iFieldNumber(aFieldNumber),iExactContentMatch(aExactContentMatch),iExtraField(aExtraField),iMissingField(aMissingField)
{iFieldName.Set(aFieldName);};
CContentType *ContentTypeLC() const;
public:
TFieldType iMapping;
TFieldType *iFieldType1;
TFieldType *iFieldType2;
TFieldType *iFieldType3;
TPtrC iFieldName;
TInt iFieldNumber;
TBool iExactContentMatch;
TFieldType *iExtraField;
TFieldType *iMissingField;
};
CContentType *TTemplateMapTest::ContentTypeLC() const
{
CContentType *ct=CContentType::NewL(*iFieldType1,iMapping);
CleanupStack::PushL(ct);
if (iFieldType2)
ct->AddFieldTypeL(*iFieldType2);
if (iFieldType3)
ct->AddFieldTypeL(*iFieldType3);
return(ct);
}
LOCAL_C void AddTestField(CContactCard* aCard,TTemplateMapTest *aTmtest, const TDesC &aText, TInt &aExtraFields)
{
if (aTmtest)
{
CContactItemField *field=AddFieldL(aCard,aTmtest->iMapping,aTmtest->iFieldName,aTmtest->iFieldType1,aTmtest->iFieldType2,aTmtest->iFieldType3);
field->TextStorage()->SetTextL(aText);
if (aTmtest->iExtraField)
aExtraFields++;
}
}
LOCAL_C void CheckFieldMappings(CContactDatabase* aDb, CContactItem *aTemplateItem, TTemplateMapTest *aTmtest1,TTemplateMapTest *aTmtest2=NULL,TTemplateMapTest *aTmtest3=NULL,TTemplateMapTest *aTmtest4=NULL)
{
CContactCard* card=CContactCard::NewLC(aTemplateItem);
//
TInt extraFields=0;
AddTestField(card,aTmtest1,_L("Test 1"),extraFields);
AddTestField(card,aTmtest2,_L("Test 2"),extraFields);
AddTestField(card,aTmtest3,_L("Test 3"),extraFields);
AddTestField(card,aTmtest4,_L("Test 4"),extraFields);
TContactItemId testCardId=aDb->AddNewContactL(*card);
CleanupStack::PopAndDestroy(); // card
//
TTemplateMapTest *testData[4]={aTmtest1,aTmtest2,aTmtest3,aTmtest4};
//ere
CContactItem *readCard=ReadContactIncHiddenFieldsLC(aDb,testCardId);
CContactItemFieldSet& fieldSet=readCard->CardFields();
CContactItemFieldSet& templateFieldSet=aTemplateItem->CardFields();
test((templateFieldSet.Count()+extraFields)==fieldSet.Count());
TInt loop=0;
for(;loop<templateFieldSet.Count();loop++)
{
const CContactItemField &field=fieldSet[loop];
const CContactItemField &templateField=templateFieldSet[loop];
for(TInt loop2=0;loop2<4;loop2++)
{
TBuf<8> fieldText;
fieldText.Format(_L("Test %d"),loop2+1);
if (field.TextStorage()->Text()==fieldText)
{
TPtrC temp = testData[loop2]->iFieldName;
test(field.Label()==temp);
TInt fieldNumber=testData[loop2]->iFieldNumber;
test((loop+1)==fieldNumber);
CContentType *ct=testData[loop2]->ContentTypeLC();
test(field.ContentType()==*ct);
TBool templateContentMatch=(templateField.ContentType()==*ct);
test(testData[loop2]->iExactContentMatch?templateContentMatch:!templateContentMatch);
test(templateField.UserFlags()==field.UserFlags());
test(templateField.ContentType()==aDb->TemplateContentType(field));
CleanupStack::PopAndDestroy(); // ct
}
}
}
TInt nextTmTest=0;
for(;loop<fieldSet.Count();loop++)
{
while(testData[nextTmTest]->iExtraField==NULL && testData[nextTmTest]->iMissingField==NULL)
nextTmTest++;
if (testData[nextTmTest]->iExtraField)
test(fieldSet[loop].ContentType().ContainsFieldType(*testData[nextTmTest]->iExtraField));
if (testData[nextTmTest]->iMissingField)
{
test(!fieldSet[loop].ContentType().ContainsFieldType(*testData[nextTmTest]->iMissingField));
test(aDb->TemplateContentType(fieldSet[loop]).ContainsFieldType(*testData[nextTmTest]->iMissingField));
}
nextTmTest++;
}
CleanupStack::PopAndDestroy(); // readCard
//
aDb->DeleteContactL(testCardId);
}
LOCAL_C void TestTemplateFieldMatchingL()
{
test.Next(_L("Create template"));
CreateDatabaseL();
CContactDatabase* db=CntTest->OpenDatabaseL();
CntTest->DeleteAllTemplateFieldsL();
//
_LIT(KField1,"Field 1");
_LIT(KField2,"Field 2");
_LIT(KField3,"Field 3");
_LIT(KField4,"Field 4");
_LIT(KField5,"Field 5");
_LIT(KField6,"Field 6");
_LIT(KField7,"Field 7");
_LIT(KField8,"Field 8");
_LIT(KField9,"Field 9");
_LIT(KFieldX1,"Field X1");
_LIT(KFieldX2,"Field X2");
_LIT(KFieldHome,"Field Home");
_LIT(KFieldWork,"Field Work");
//
CContactTemplate *contactTemplate=(CContactTemplate *)db->OpenContactLX(db->TemplateId());
CleanupStack::PushL(contactTemplate);
TFieldType mapping1(TUid::Uid(1));
TFieldType mapping2(TUid::Uid(2));
TFieldType mapping3(TUid::Uid(3));
TFieldType mapping4(TUid::Uid(4));
TFieldType mappingX(KUidContactFieldVCardMapUnusedN);
TFieldType fieldType1(TUid::Uid(101));
TFieldType fieldType2(TUid::Uid(102));
TFieldType fieldType3(TUid::Uid(103));
TFieldType fieldType4(TUid::Uid(104));
TFieldType fieldType5(TUid::Uid(105));
TFieldType fieldTypeHome(TUid::Uid(KIntContactFieldVCardMapHOME));
TFieldType fieldTypeWork(TUid::Uid(KIntContactFieldVCardMapWORK));
AddFieldL(contactTemplate,mapping1,KField1());
SetUserFlags(contactTemplate,1);
AddFieldL(contactTemplate,mapping2,KField2(),&fieldType2);
SetUserFlags(contactTemplate,2);
AddFieldL(contactTemplate,mapping2,KField3(),&fieldType3);
SetUserFlags(contactTemplate,3);
AddFieldL(contactTemplate,mapping3,KField4(),&fieldType2);
SetUserFlags(contactTemplate,0);
AddFieldL(contactTemplate,mapping3,KField5(),&fieldType2,&fieldType4);
SetUserFlags(contactTemplate,1);
AddFieldL(contactTemplate,mapping3,KField6(),&fieldType2,&fieldType1);
SetUserFlags(contactTemplate,2);
AddFieldL(contactTemplate,mapping4,KField8(),&fieldType4);
SetUserFlags(contactTemplate,3);
InsertFieldL(contactTemplate,mapping4,6,KField7());
SetUserFlags(contactTemplate,0);
AddFieldL(contactTemplate,mapping4,KField9(),&fieldType4,&fieldType2,&fieldType1);
SetUserFlags(contactTemplate,1);
AddFieldL(contactTemplate,mappingX,KFieldX1());
SetUserFlags(contactTemplate,2);
AddFieldL(contactTemplate,mappingX,KFieldX2(),&fieldType2);
SetUserFlags(contactTemplate,3);
AddFieldL(contactTemplate,mapping1,KFieldHome(),&fieldType1,&fieldType5,&fieldTypeHome);
SetUserFlags(contactTemplate,0);
AddFieldL(contactTemplate,mapping1,KFieldWork(),&fieldType1,&fieldType5,&fieldTypeWork);
SetUserFlags(contactTemplate,0);
db->CommitContactL(*contactTemplate);
CleanupStack::PopAndDestroy(); // contactTemplate
CleanupStack::Pop(); // contactTemplate.Close()
//
TTemplateMapTest tmTest1(mapping1,&fieldType4,NULL,NULL,KField1(),1,EFalse);
TTemplateMapTest tmTest2(mapping2,&fieldType1,NULL,NULL,KField2(),2,EFalse);
TTemplateMapTest tmTest3(mapping2,&fieldType2,NULL,NULL,KField2(),2,ETrue);
TTemplateMapTest tmTest4(mapping2,&fieldType3,NULL,NULL,KField3(),3,ETrue);
TTemplateMapTest tmTest5(mapping3,&fieldType4,NULL,NULL,KField5(),5,EFalse);
TTemplateMapTest tmTest6(mapping3,&fieldType1,NULL,NULL,KField6(),6,EFalse);
TTemplateMapTest tmTest7(mapping3,&fieldType2,&fieldType4,NULL,KField5(),5,ETrue);
TTemplateMapTest tmTest8(mapping4,&fieldType3,NULL,NULL,KField7(),7,EFalse);
TTemplateMapTest tmTest9(mapping4,&fieldType4,NULL,NULL,KField8(),8,ETrue);
TTemplateMapTest tmTest10(mapping4,&fieldType4,&fieldType2,NULL,KField9(),9,EFalse);
TTemplateMapTest tmTestX1(mappingX,&fieldType4,NULL,NULL,KFieldX1(),10,EFalse,&mappingX);
TTemplateMapTest tmTestX2(mappingX,&fieldType2,NULL,NULL,KFieldX2(),11,ETrue);
TTemplateMapTest tmTestWork(mapping1,&fieldType1,&fieldType5,NULL,KFieldWork(),13,EFalse,NULL,&fieldTypeWork);//zzz change to work
contactTemplate=(CContactTemplate *)ReadContactIncHiddenFieldsLC(db,db->TemplateId());
CheckFieldMappings(db,contactTemplate,&tmTest1);
CheckFieldMappings(db,contactTemplate,&tmTest1,&tmTest3,&tmTest4);
CheckFieldMappings(db,contactTemplate,&tmTest5,&tmTest2,&tmTest1,&tmTest6);
CheckFieldMappings(db,contactTemplate,&tmTest7,&tmTest10,&tmTest8);
CheckFieldMappings(db,contactTemplate,&tmTest9);
CheckFieldMappings(db,contactTemplate,&tmTestX1);
CheckFieldMappings(db,contactTemplate,&tmTestX2);
CheckFieldMappings(db,contactTemplate,&tmTestWork);
//
CleanupStack::PopAndDestroy(); // contactTemplate
CntTest->CloseDatabase();
}
LOCAL_C void TestTemplateContentTypeL()
{
CreateDatabaseL();
CContactDatabase* db=CntTest->OpenDatabaseL();
CContactItem* systemTemplate=ReadContactIncHiddenFieldsLC(db,db->TemplateId());
CContactCard *card=CContactCard::NewLC(systemTemplate);
CContactItemFieldSet& fieldSet=card->CardFields();
for(TInt loop=0;loop<fieldSet.Count();loop++)
test(db->TemplateContentType(fieldSet[loop])==fieldSet[loop].ContentType());
CleanupStack::PopAndDestroy(2); // systemTemplate,card
CntTest->CloseDatabase();
}
LOCAL_C void TestMultiTemplateCacheL()
{
test.Next(_L("Create template"));
CreateDatabaseL();
CContactDatabase* db=CntTest->OpenDatabaseL();
CntTest->DeleteAllTemplateFieldsL();
//
CContactTemplate* contactTemplate=CContactTemplate::NewLC();
TContactItemId id1=db->AddNewContactL(*contactTemplate);
CleanupStack::PopAndDestroy(); // contactTemplate
contactTemplate=(CContactTemplate *)db->ReadContactLC(id1);
// add fields to cards
AddFieldL(contactTemplate,KUidContactFieldGivenName,_L("First name"),_L("Bilbo"));
AddFieldL(contactTemplate,KUidContactFieldFamilyName,_L("Surname"),_L("Baggins"));
AddFieldL(contactTemplate,KUidContactFieldCompanyName,_L("Company"),_L("Great Ape Software"));
TDateTime dt(1965,EJuly,15,0,0,0,0);
AddDateFieldL(contactTemplate,KUidContactFieldNone,_L("Birthday"),&dt);
//
TContactItemId templateId=db->AddNewContactL(*contactTemplate);
//
doTestTemplate(db,templateId,contactTemplate,EFalse);
CleanupStack::PopAndDestroy(); // contactTemplate
CntTest->CloseDatabase();
}
LOCAL_C void TestTemplateL()
{
test.Next(_L("Create template"));
CreateDatabaseL();
CContactDatabase* db=CntTest->OpenDatabaseL();
CntTest->DeleteAllTemplateFieldsL();
//
CContactTemplate* contactTemplate=CContactTemplate::NewLC();
TContactItemId id1=db->AddNewContactL(*contactTemplate);
CleanupStack::PopAndDestroy(); // contactTemplate
contactTemplate=(CContactTemplate *)db->ReadContactLC(id1);
// add fields to cards
AddFieldL(contactTemplate,KUidContactFieldGivenName,_L("First name"),_L("Bilbo"));
AddFieldL(contactTemplate,KUidContactFieldFamilyName,_L("Surname"),_L("Baggins"));
AddFieldL(contactTemplate,KUidContactFieldCompanyName,_L("Company"),_L("Great Ape Software"));
TDateTime dt(1965,EJuly,15,0,0,0,0);
AddDateFieldL(contactTemplate,KUidContactFieldNone,_L("Birthday"),&dt);
//
TContactItemId templateId=db->AddNewContactL(*contactTemplate);
//
doTestTemplate(db,templateId,contactTemplate,EFalse);
CleanupStack::PopAndDestroy(); // contactTemplate
CntTest->CloseDatabase();
}
LOCAL_C void TestSystemTemplateFieldsL()
{
// create a new db and checks the template fields for instances of LOGO, PHOTO, JOB TITLE
CContactDatabase* db=CntTest->CreateDatabaseL();
CContactTemplate *contactTemplate=(CContactTemplate *)db->OpenContactLX(db->TemplateId());
CleanupStack::PushL(contactTemplate);
CContactItemFieldSet& templateFieldSet = contactTemplate->CardFields();
TInt templateFieldCount = templateFieldSet.Count();
TBool titleFound=EFalse;
TBool logoFound=EFalse;
TBool photoFound=EFalse;
for (TInt ii=0; ii < templateFieldCount; ii++)
{
// JOB TITLE SEARCH
if (templateFieldSet[ii].ContentType().ContainsFieldType(KUidContactFieldVCardMapTITLE))
{
// SATISFIED
titleFound=ETrue;
}
// LOGO SEARCH
if (templateFieldSet[ii].ContentType().ContainsFieldType(KUidContactFieldVCardMapLOGO))
{
// SATISFIED
logoFound=ETrue;
}
// LOGO SEARCH
if (templateFieldSet[ii].ContentType().ContainsFieldType(KUidContactFieldVCardMapPHOTO))
{
// SATISFIED
photoFound=ETrue;
}
};
test(photoFound);
test(logoFound);
test(titleFound);
CleanupStack::PopAndDestroy(2); // contactTemplate,contactTemplate.Close()
//
CntTest->CloseDatabase();
}
/**
* Regression testcode for EDNSKSA-53ZKXM "Problem with TemplateRefId"
*/
void TestTemplateReferenceCountingL()
{
CreateDatabaseL();
CContactDatabase* db=CntTest->OpenDatabaseL();
//create a template and a card based on it
_LIT(KUserDefinedTemplate,"MyTemplate");
CContactItem* temp = db->CreateContactCardTemplateLC(KUserDefinedTemplate);
CContactItem* card = CContactCard::NewLC(temp);
TContactItemId one= db->AddNewContactL(*card);
CleanupStack::PopAndDestroy(card);
CleanupStack::PopAndDestroy(temp);
//increment reference count (simulate synchronisation)
CContactItem* card2 = db->OpenContactLX(one);
CleanupStack::PushL(card2);
card2->IncAccessCount();
db->CommitContactL(*card2);
CleanupStack::PopAndDestroy(card2);
CleanupStack::PopAndDestroy();//lock record
//delete both synchronised copies
db->DeleteContactL(one);
db->DeleteContactL(one);
CntTest->CloseDatabase();
}
/**
* Test Case required for INC078981 "Contacts model field type mathching urgent fix"
*/
LOCAL_C void TestTemplateFieldTypeMatchingL()
{
test.Next(_L("Create template"));
CreateDatabaseL();
CContactDatabase* db=CntTest->OpenDatabaseL();
CntTest->DeleteAllTemplateFieldsL();
_LIT(KField1,"Field 1");
CContactTemplate *contactTemplate=(CContactTemplate *)db->OpenContactLX(db->TemplateId());
CleanupStack::PushL(contactTemplate);
TFieldType mapping1(TUid::Uid(KIntContactFieldVCardMapSIPID));
TFieldType mappingX(TUid::Uid(KIntContactFieldVCardMapSIPID));
TFieldType mapping2(TUid::Uid(KIntContactFieldVCardMapVOIP));
TFieldType mapping3(TUid::Uid(3));
TFieldType mapping4(TUid::Uid(4));
TFieldType fieldType1(TUid::Uid(KUidContactFieldSIPIDValue));
TFieldType fieldType2(TUid::Uid(KIntContactFieldVCardMapVOIP));
AddFieldL(contactTemplate,mapping1,KField1(),&fieldType1,&mappingX);
AddFieldL(contactTemplate,mapping1,KField1(),&fieldType1,&mapping2);
AddFieldL(contactTemplate,mapping1,KField1(),&fieldType1,&mapping3);
AddFieldL(contactTemplate,mapping1,KField1(),&fieldType1,&mapping4);
db->CommitContactL(*contactTemplate);
CleanupStack::PopAndDestroy(); // contactTemplate
CleanupStack::Pop(); // contactTemplate.Close()
TTemplateMapTest tmTest1(mapping1,&fieldType1,&mappingX,NULL,KField1(),1,ETrue);
TTemplateMapTest tmTest2(mapping1,&fieldType1,&mapping2,NULL,KField1(),2,ETrue);
TTemplateMapTest tmTest3(mapping1,&fieldType1,&mapping3,NULL,KField1(),3,ETrue);
TTemplateMapTest tmTest4(mapping1,&fieldType1,&mapping4,NULL,KField1(),4,ETrue);
TTemplateMapTest tmTest5(mapping1,&fieldType2,&mappingX,NULL,KField1(),1,EFalse);
contactTemplate=(CContactTemplate *)ReadContactIncHiddenFieldsLC(db,db->TemplateId());
CheckFieldMappings(db,contactTemplate,&tmTest1);
CheckFieldMappings(db,contactTemplate,&tmTest3);
CheckFieldMappings(db,contactTemplate,&tmTest2);
CheckFieldMappings(db,contactTemplate,&tmTest4);
CheckFieldMappings(db,contactTemplate,&tmTest5);
CleanupStack::PopAndDestroy(); // contactTemplate
CntTest->CloseDatabase();
}
/**
@SYMTestCaseID PIM-T-TEMPL-INC100029-0001
@SYMTestType UT
@SYMTestPriority Critical
@SYMDEF INC100029
@SYMTestCaseDesc Tests that if an attempt is made to commit the System template
with a field which contains data that the commit leaves with KErrNotSupported.
@SYMTestActions
1. Open the System template.
2. Add data to the field KUidContactFieldGivenName.
3. Commit the System template.
4. Check that step 3 leaves with error KErrNotSupported.
@SYMTestExpectedResults As per Test Action 4.
*/
LOCAL_C void TestTemplateFieldModificationL()
{
test.Next( _L("@SYMTestCaseID:PIM-T-TEMPL-INC100029-0001 Validate template field modification") );
CContactDatabase* db = CntTest->OpenDatabaseL();
//
// 1. Open the System template.
//
CContactTemplate* contactTemplate = static_cast<CContactTemplate*>( db->OpenContactLX( db->TemplateId() ) );
CleanupStack::PushL( contactTemplate );
//
// 2. Add data to the field KUidContactFieldGivenName.
//
SetNameL(*contactTemplate, KUidContactFieldGivenName, _L("Invalid"), EFalse );
//
// 3. Commit the System template.
//
TRAPD( err, db->CommitContactL( *contactTemplate ) );
//
// 4. Check that step 3 leaves with error KErrNotSupported.
//
test( err == KErrNotSupported );
CleanupStack::PopAndDestroy(2); // contactTemplate and lock.
CntTest->CloseDatabase();
}
LOCAL_C void TestAsyncOpenDbAndAddTemplateL()
{
//test if necesary sanity check was made
test.Next( _L("Open async database and simulate a template add events"));
TRequestStatus requestStatus(0);
CContactOpenOperation* op = CContactDatabase::Open(KDatabaseFileName, requestStatus);
// note: op doesn't have to be on CS
User::WaitForRequest(requestStatus);
CContactDatabase* database = op->TakeDatabase();
CleanupStack::PushL(database);
//simulate a template add event
TContactDbObserverEvent event;
event.iType = EContactDbObserverEventTemplateAdded;
database->HandleDatabaseEventL(event);
CleanupStack::PopAndDestroy(database);
}
LOCAL_C void TestAsyncOpenDbAndDeleteTemplateL()
{
//test if necesary sanity check was made
test.Next( _L("Open async database and simulate a template delete event"));
TRequestStatus requestStatus(0);
CContactOpenOperation* op = CContactDatabase::Open(KDatabaseFileName, requestStatus);
// note: op doesn't have to be on CS
User::WaitForRequest(requestStatus);
CContactDatabase* database = op->TakeDatabase();
CleanupStack::PushL(database);
//simulate a template remove event
TContactDbObserverEvent event;
event.iType = EContactDbObserverEventTemplateDeleted;
database->HandleDatabaseEventL(event);
CleanupStack::PopAndDestroy(database);
}
LOCAL_C void TestAsyncOpenDbAndDeleteContactL()
{
//test if necesary sanity check was made
test.Next( _L("Open async database and simulate a template delete event"));
TRequestStatus requestStatus(0);
CContactOpenOperation* op = CContactDatabase::Open(KDatabaseFileName, requestStatus);
// note: op doesn't have to be on CS
User::WaitForRequest(requestStatus);
CContactDatabase* database = op->TakeDatabase();
CleanupStack::PushL(database);
TContactItemId contactId = 1; //anything but not system template
database->DeleteContactL(contactId); //aim is to check if it's safe to delete from template
CleanupStack::PopAndDestroy(database);
}
/**
@SYMTestCaseID PIM-T-TEMPL-0001
*/
void DoTestsL()
{
test.Start(_L("@SYMTestCaseID:PIM-T-TEMPL-0001 Create new database"));
CreateDatabaseL();
TestTemplateLabelsL();
TestSystemTemplateL();
TestSystemTemplateRestorationL();
TestTemplateContentTypeL();
TestTemplateL();
TestMultiTemplateCacheL();
TestTemplateFieldMatchingL();
TestSystemTemplateFieldsL();
TestTemplateReferenceCountingL();
TestTemplateFieldTypeMatchingL();
TestTemplateFieldModificationL();
TestAsyncOpenDbAndAddTemplateL();
TestAsyncOpenDbAndDeleteTemplateL();
TestAsyncOpenDbAndDeleteContactL();
test.Next(_L("Delete database"));
CntTest->DeleteDatabaseL();
}
GLDEF_C TInt E32Main()
{
CntTest=new(ELeave) CCntTest;
CntTest->ConstructL(test,KDatabaseFileName);
TRAPD(err,DoTestsL());
CntTest->EndTestLib(err);
return KErrNone;
}