--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines_old/contactsmodel/tsrc/t_cntvcard.cpp Fri Jun 11 13:29:23 2010 +0300
@@ -0,0 +1,2139 @@
+// Copyright (c) 2002-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:
+// Unit tests for functionality delivered by the CNTVCARD.DLL library.
+// This test contains the tests originally in T_EXPDEL
+//
+//
+
+#include <e32test.h>
+#include <f32file.h>
+#include <s32file.h>
+#include <s32mem.h>
+#include <cntdb.h>
+#include <cntvcard.h>
+#include <cntitem.h>
+#include <cntfldst.h>
+#include <e32def.h>
+#include "t_utils2.h"
+#include "T_rndutils.h"
+#include <coreappstest/testserver.h>
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include "cntdb_internal.h"
+#endif
+
+_LIT(KTestName,"T_CNTVCARD");
+
+
+
+_LIT(KDatabaseFileName,"C:T_CNTVCARD");
+
+_LIT(KVcard1, "Z:\\t_cntvcard\\email1.vcf");
+_LIT(KVcard2, "Z:\\t_cntvcard\\email2.vcf");
+
+
+_LIT(KOutputFileName, "C:\\Test_Output.txt");
+_LIT(KExpDelAFileName, "c:\\expdela");
+_LIT(KTestVcardFile, "Z:\\cntvcard\\testvcard.vcf");
+
+_LIT(KImpTypeVcardName, "Z:\\t_cntvcard\\testTypeVcard.vcf");
+_LIT(KImpNoTypeVcardName, "Z:\\t_cntvcard\\testNoTypeVcard.vcf");
+
+_LIT(KTestVcardFile1, "Z:\\cntvcard\\testvcard1.vcf");
+//UpdateVCardL
+_LIT(KVCardUpdate1,"Z:\\System\\Programs\\CntmodelTest\\vcardupdate1.vcf");
+_LIT(KVCardUpdate2,"C:\\vcardupdate2.vcf");
+_LIT(KVCardUpdate3,"Z:\\System\\Programs\\CntmodelTest\\vcardupdate3.vcf");
+
+// digram data files
+_LIT(KFirstNameFileName,"z:\\cntvcard\\names.first.2gm");
+_LIT(KLastNameFileName,"z:\\cntvcard\\names.last.2gm");
+
+// vcard terminated by LF
+_LIT(KVCardFileLF,"z:\\t_cntvcard\\cntvcardLF.vcf");
+// vcard containing UID property
+_LIT(KVCardFileUID,"z:\\t_cntvcard\\cntvcardUID.vcf");
+
+_LIT8(KVCardBinaryKeyImportFileDes,"BEGIN:VCARD\r\n"
+ "VERSION:2.1\r\n"
+ "REV:20061120T111808Z\r\n"
+ "UID:0000000000000000-00e1005eee8a27d8-44\r\n"
+ "N:Name;;;;\r\n"
+ "TEL;HOME;VOICE;CELL:1111\r\n"
+ "KEY;ENCODING=BASE64:MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQA\r\n"
+ "wdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENbW11bmljYX\r\n"
+ "Rpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0\r\n"
+ "ZW1zMRwwGgYDVQQDExNyb290Y2EubmV0c2NhcGUuY29tMB4XDTk3MDYwNj\r\n"
+ "E5NDc1OVoXDTk3MTIwMzE5NDc1OVowgYkxCzAJBgNVBAYTAlVTMSYwJAYD\r\n"
+ "VQQKEx1OZXRzY2FwZSBDb21tdW5pY2F0aW9ucyBDb3JwLjEYMBYGA1UEAx\r\n"
+ "MPVGltb3RoeSBBIEhvd2VzMSEwHwYJKoZIhvcNAQkBFhJob3dlc0BuZXRz\r\n"
+ "Y2FwZS5jb20xFTATBgoJkiaJk/IsZAEBEwVob3dlczBcMA0GCSqGSIb3DQ\r\n"
+ "EBAQUAA0sAMEgCQQC0JZf6wkg8pLMXHHCUvMfL5H6zjSk4vTTXZpYyrdN2\r\n"
+ "dXcoX49LKiOmgeJSzoiFKHtLOIboyludF90CgqcxtwKnAgMBAAGjNjA0MB\r\n"
+ "EGCWCGSAGG+EIBAQQEAwIAoDAfBgNVHSMEGDAWgBT84FToB/GV3jr3mcau\r\n"
+ "+hUMbsQukjANBgkqhkiG9w0BAQQFAAOBgQBexv7o7mi3PLXadkmNP9LcIP\r\n"
+ "mx93HGp0Kgyx1jIVMyNgsemeAwBM+MSlhMfcpbTrONwNjZYW8vJDSoi//y\r\n"
+ "rZlVt9bJbs7MNYZVsyF1unsqaln4/vy6Uawfg8VUMk1U7jt8LYpo4YULU7\r\n"
+ "UZHPYVUaSgVttImOHZIKi4hlPXBOhcUQ==\r\n"
+ "\r\n"
+ "PHOTO;ENCODING=BASE64:\r\n"
+ " ZmlsZTovLy9qcXB1YmxpYy5naWY=\r\n"
+ "\r\n"
+ "END:VCARD\r\n"
+ );
+
+_LIT8(KVCardTextKeyImportFileDes,"BEGIN:VCARD\r\n"
+ "VERSION:2.1\r\n"
+ "REV:20061120T111808Z\r\n"
+ "UID:0000000000000000-00e1005eee8a27d8-44\r\n"
+ "N:Name;;;;\r\n"
+ "TEL;HOME;VOICE;CELL:1111\r\n"
+ "KEY:X509\r\n"
+ "PHOTO;ENCODING=BASE64:\r\n"
+ " ZmlsZTovLy9qcXB1YmxpYy5naWY=\r\n"
+ "\r\n"
+ "END:VCARD\r\n"
+ );
+
+_LIT8(KMultiParam,"BEGIN:VCARD\r\n"
+ "VERSION:2.1\r\n"
+ "N:;Neo;;Mr.;\r\n"
+ "FN:Mr. TestName\r\n"
+ "TEL;TYPE=HOME;TYPE=VOICE;TYPE=CELL:123\r\n"
+ "END:VCARD\r\n"
+ );
+_LIT8(KTelExport, "TEL;HOME;VOICE;CELL:123\r\n");
+
+_LIT8(KVCardBeforeChange,"BEGIN:VCARD\r\n"
+ "VERSION:2.1\r\n"
+ "N:Jm;Jg;;;\r\n"
+ "TEL;HOME:11111\r\n"
+ "TEL;HOME:67890\r\n"
+ "TEL;CELL:12345\r\n"
+ "UID:4c2d2b19ef07adea-00e115956542fd28-1\r\n"
+ "END:VCARD\r\n"
+ );
+
+ _LIT8(KVCardAfterChange,"BEGIN:VCARD\r\n"
+ "VERSION:2.1\r\n"
+ "N:Jm;Jg;;;\r\n"
+ "TEL;HOME:11112\r\n"
+ "TEL;HOME:22222\r\n"
+ "TEL;HOME:22223\r\n"
+ "TEL;HOME:22224\r\n"
+ "UID:4c2d2b19ef07adea-00e115956542fd28-1\r\n"
+ "END:VCARD\r\n"
+ );
+
+ _LIT(KGivenName, "Jg");
+ _LIT(KFamilyName, "Jm");
+ _LIT(KTelHome1,"11111");
+ _LIT(KTelHome2,"67890");
+ _LIT(KTelCell,"12345");
+ _LIT(KTelHome1Modified,"11112");
+ _LIT(KTelHome2Modified,"22222");
+ _LIT(KTelHome3Modified,"22223");
+ _LIT(KTelHome4Modified,"22224");
+
+//vCard containing CompanyField
+_LIT(KVCardWithCompany, "z:\\t_cntvcard\\withcompany.vcf");
+//vCard without CompanyField
+_LIT(KVCardWithoutCompany, "z:\\t_cntvcard\\withoutcompany.vcf");
+
+_LIT(KVCardLargePhoto, "Z:\\t_cntvcard\\vcardwithlargephoto.vcf");
+
+
+CCntTest* CntTest=NULL;
+LOCAL_D RTest test(KTestName);
+
+LOCAL_C void TestCondition(TBool aCondition, TInt aLineNumber);
+#define TEST_CONDITION(x) TestCondition(x, __LINE__)
+
+const TInt KNumAccessCountContacts= 5;
+const TInt KMachineUniqueId=0;
+const TInt KNumberOfRandomContacts = 40;
+
+_LIT(KName,"Name");
+_LIT(KPhoneNumber,"1111");
+_LIT8(KModifiedNumberProperty,"TEL;HOME;CELL:11112222\r\n"); //no VOICE parameter!
+_LIT8(KModifiedNumberProperty2,"tel;work;cell;2:4444\r\ntel;home;Voice;CELL:\r\n"); //empty property to delete
+_LIT8(KModifiedNumberProperty3,"TEL;HOME;CELL:\r\nTEL;HOME;CELL:3333\r\n");
+
+_LIT(KVCardFile1,"c:\\cntvcard1.vcf");
+_LIT(KVCardFile2,"c:\\cntvcard2.vcf");
+_LIT(KVCardFile3,"c:\\cntvcard3.vcf");
+
+// data we expect to see in KTestVcardFile
+_LIT(KFirstName, "first");
+_LIT(KFirstNamePrn, "f-i-r-s-t");
+_LIT(KSurName, "last");
+_LIT(KSurNamePrn, "l-a-s-t");
+_LIT(KOrgName, "I work here");
+_LIT(KOrgNamePrn, "Eye w-o-r-k h-e-r-e");
+
+// labels we expect from the conacts resource file
+_LIT(KFirstNameLabel, "First name");
+_LIT(KFirstNamePrnLabel, "First name reading");
+_LIT(KSurNameLabel, "Last name");
+_LIT(KSurNamePrnLabel, "Last name reading");
+_LIT(KOrgNameLabel, "Company");
+_LIT(KOrgNamePrnLabel, "Company reading");
+
+_LIT(KVCardFile5, "c:\\cntvcard5.vcf");
+_LIT(KVCardFile6, "c:\\cntvcard6.vcf");
+_LIT8(KMasterVcard, "BEGIN:VCARD\r\n"
+ "VERSION:2.1\r\n"
+ "REV:20060821T131829Z\r\n"
+ "UID:f356da00bfd5320f-00e0f93a015e3ec0-18\r\n"
+ "N:Aaaa;Pekka;;;\r\n"
+ "END:VCARD\r\n"
+ "BEGIN:VCARD\r\n"
+ "VERSION:2.1\r\n"
+ "REV:20060821T131916Z\r\n"
+ "UID:f356da00bfd5320f-00e0f93a015e8128-19\r\n"
+ "N:Bbb;Pekka;;;\r\n"
+ "END:VCARD\r\n"
+ "BEGIN:VCARD\r\n"
+ "VERSION:2.1\r\n"
+ "REV:20060821T131829Z\r\n"
+ "UID:f356da00bfd5320f-00e0f93a015eb46d-20\r\n"
+ "N:Cccc;Pekka;;;\r\n"
+ "END:VCARD\r\n"
+);
+_LIT8(KModifierVcard,"BEGIN:VCARD\r\n"
+ "VERSION:2.1\r\n"
+ "REV:20060821T131829Z\r\n"
+ "UID:f356da00bfd5320f-00e0f93a015e3ec0-18\r\n"
+ "N:Aaaa;Pekka;;;\r\n"
+ "END:VCARD\r\n"
+ "BEGIN:VCARD\r\n"
+ "VERSION:2.1\r\n"
+ "REV:20060821T131916Z\r\n"
+ "UID:f356da00bfd5320f-00e0f93a015e8128-19\r\n"
+ "N:;Pekka;;;\r\n"
+ "END:VCARD\r\n"
+ "BEGIN:VCARD\r\n"
+ "VERSION:2.1\r\n"
+ "REV:20060821T131829Z\r\n"
+ "UID:f356da00bfd5320f-00e0f93a015eb46d-20\r\n"
+ "N:Cccc;Pekka;;;\r\n"
+ "END:VCARD\r\n"
+);
+
+_LIT8(KPartialVCard,"BEGIN:VCARD\r\n"
+ "\r"
+);
+
+const TAny* GNames[] = {&KFirstName, &KFirstNamePrn, &KSurName, &KSurNamePrn, &KOrgName, &KOrgNamePrn};
+const TAny* GLabels[] = {&KFirstNameLabel, &KFirstNamePrnLabel, &KSurNameLabel, &KSurNamePrnLabel, &KOrgNameLabel, &KOrgNamePrnLabel};
+
+const TInt KNumberOfExtendedFieldNames=6;
+
+const TInt KExtendedFieldNames[KNumberOfExtendedFieldNames] =
+ {
+ KUidContactFieldGivenNameValue,
+ KUidContactFieldGivenNamePronunciationValue,
+ KUidContactFieldFamilyNameValue,
+ KUidContactFieldFamilyNamePronunciationValue,
+ KUidContactFieldCompanyNameValue,
+ KUidContactFieldCompanyNamePronunciationValue,
+ };
+
+
+/** Tests for default VOICE property parameter handling (tests1-4), and the X-IRMC-x extentions for the SOUND property (tests 5-6) */
+class CDefaultVoiceParamTests : public CBase
+ {
+public :
+ enum THowToCheck {ECheckValue = 1, ECheckLabel = 2, EAppendValue = 4, EAppendLabel = 8};
+
+public:
+ static CDefaultVoiceParamTests* NewLC(CCntTest& aTestLibrary);
+ ~CDefaultVoiceParamTests();
+ void RunTestsL();
+private:
+ CDefaultVoiceParamTests(CCntTest& aTestLibrary);
+ void ConstructL();
+ void TestOneL();
+ void TestTwoL();
+ void TestThreeL();
+ void TestFourL();
+ void TestFiveL();
+ void TestSixL();
+ void ImportContactsL(const TDesC& aFileName);
+ void ExportContactsL(const TDesC& aFileName, const CContactIdArray* aIds);
+ void CreateTestDataL(TContactItemId aId, const TDesC& aFileName, const TDesC8& aVCardData);
+ TInt CountPhoneNumberFieldsL(TContactItemId aId);
+ TContactItemId CreateItemL(const TDesC& aName, const TDesC& aNumber);
+ static void CheckCard(CContactCard* aCard, CDesCArray* aFields = NULL, CDesCArray* aLabels =NULL, TUint aFlags = ECheckValue|ECheckLabel);
+ void CheckCardL(TContactItemId aId, CDesCArray* aFields = NULL, CDesCArray* aLabels =NULL, TUint aFlags = ECheckValue|ECheckLabel) const;
+
+private:
+ CCntTest& iTest;
+ CContactDatabase* iDb;
+ };
+
+CDefaultVoiceParamTests* CDefaultVoiceParamTests::NewLC(CCntTest& aTestLibrary)
+ {
+ CDefaultVoiceParamTests* self = new(ELeave) CDefaultVoiceParamTests(aTestLibrary);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+CDefaultVoiceParamTests::~CDefaultVoiceParamTests()
+ {
+ }
+
+void CDefaultVoiceParamTests::RunTestsL()
+ {
+ TestFiveL(); //these two have to run 1st since tests 1-4 leave the db in an inconvenient state
+ TestSixL();
+ TestOneL();
+#if defined(_DEBUG)
+ //this test cannot be run in release mode due to UID mismatch.
+ TestTwoL();
+#endif
+ TestThreeL();
+ TestFourL();
+ }
+
+CDefaultVoiceParamTests::CDefaultVoiceParamTests(CCntTest& aTestLibrary) : iTest(aTestLibrary)
+ {
+ }
+
+void CDefaultVoiceParamTests::ConstructL()
+ {
+ iDb=iTest.CreateDatabaseL();
+ iDb->OverrideMachineUniqueId(KMachineUniqueId);
+ }
+
+/** Check all the fields specified by KExtendedFieldNames for correctness.
+ The specific behaviour on what is checked is regulated by aFlags.
+ This also prints each field with its label.
+
+ @param aFields If present and the ECheckValue bit of aFlags set, the nth field text value is compared against
+ the nth descriptor in aFields.
+ If present and EAppendValue bit of aFlags set, each field's text value is appended to the end of aFields.
+
+ @param aLabels If present and the ECheckLabel bit of aFlags set, the nth field's label is compared against
+ the nth descriptor in ECheckLabel.
+ If present and EAppendLabel bit of aFlags set, each field's label is appended to the end of aLabels.
+ @param aFlags Bitfields indicating how aFields and aLabels are used. Note that some values from THowToCheck
+ (like ECheckValue and EAppendValue) cannot be used at the same time.
+ */
+void CDefaultVoiceParamTests::CheckCard(CContactCard* aCard, CDesCArray* aFields, CDesCArray* aLabels, TUint aFlags)
+ {
+ CContactItemFieldSet& fieldSet=aCard->CardFields();
+ for(TInt i=0;i<KNumberOfExtendedFieldNames;i++)
+ {
+ TInt index = fieldSet.Find( TUid::Uid(KExtendedFieldNames[i]));
+ TEST_CONDITION(index != KErrNotFound);
+ TPtrC text;
+ if(aFields && (ECheckValue& aFlags))
+ {
+ TPtrC compare((*aFields)[i]);
+ TBool succeed(EFalse);
+ while(index != KErrNotFound)
+ {
+ text.Set(fieldSet[index].TextStorage()->Text());
+ succeed = (text.Compare(compare)==0);
+ if(succeed)
+ {
+ break;
+ }
+ index = fieldSet.FindNext( TUid::Uid(KExtendedFieldNames[i]), index + 1);
+ }
+ TEST_CONDITION(succeed);
+ }
+ else if (aFields && (aFlags & EAppendValue))
+ {
+ text.Set(fieldSet[index].TextStorage()->Text());
+ TRAP_IGNORE(aFields->AppendL(text));
+ }
+
+ TPtrC label(fieldSet[index].Label());
+ if(aLabels && (ECheckLabel& aFlags))
+ {
+ TPtrC comparelabel((*aLabels)[i]);
+ TEST_CONDITION(label.Compare(comparelabel)==0);
+ }
+ else if (aLabels && (aFlags & EAppendLabel))
+ {
+ TRAP_IGNORE(aLabels->AppendL(label));
+ }
+ test.Printf(_L("%S: %S\n") ,&label, &text); // print this just to make sure
+ }
+}
+
+void CDefaultVoiceParamTests::CheckCardL(TContactItemId aId, CDesCArray* aFields, CDesCArray* aLabels, TUint aFlags) const
+ {
+ CContactCard* card = STATIC_CAST(CContactCard*, iDb->OpenContactL(aId));
+ CleanupStack::PushL(card);
+ CheckCard(card, aFields, aLabels, aFlags);
+ iDb->CloseContactL(aId);
+ CleanupStack::PopAndDestroy(card);
+ }
+
+/**
+Default number is edited in PIM and synchronisation is started.
+Default number is not edited in phone but new number is inserted
+
+1. Choose a phone number field of a phone contact as a default (For example Tel home: 1111)
+2. Start synchronisation
+3. Edit the contact's default number in PIM (For example Home: 1111 -> 11112222)
+4. Start synchronisation
+5. Default number wasn't amended in phone but new edited number detail (Tel Home 11112222) was created.
+*/
+void CDefaultVoiceParamTests::TestOneL()
+ {
+ TContactItemId id = CreateItemL(KName(),KPhoneNumber());
+
+ CContactIdArray* array = CContactIdArray::NewLC();
+ array->AddL(id);
+
+
+ ExportContactsL(KVCardFile1,array);
+ CreateTestDataL(id, KVCardFile2,KModifiedNumberProperty);
+ ImportContactsL(KVCardFile2);
+ ExportContactsL(KVCardFile3,array); //for checking
+ CleanupStack::PopAndDestroy(array);
+
+ TEST_CONDITION(CountPhoneNumberFieldsL(id)==1); //no new field was created
+ }
+
+/**
+Case2
+Default number is deleted from PIM and new number is created in PIM.
+After synchronisation default number is not deleted from PIM and new number is not created to phone.
+(If default number is deleted only and synch is started, default number is not deleted from phone)
+
+ 1. Choose a phone number field of a phone contact as a default
+ (For example Tel home: 1111)
+ 2. Start Synchronisation
+ 3. Delete default number (Home:1111) in PIM and create a new number in PIM (Work2: 4444)
+ 4. Start synchronisation
+ 5. Default number wasn't deleted from phone and new number wasn't inserted to phone
+*/
+void CDefaultVoiceParamTests::TestTwoL()
+ {
+ TContactItemId id = CreateItemL(KName,KPhoneNumber);
+
+ CContactIdArray* array = CContactIdArray::NewLC();
+ array->AddL(id);
+ ExportContactsL(KVCardFile1,array);
+ CreateTestDataL(id,KVCardFile2,KModifiedNumberProperty2);
+ ImportContactsL(KVCardFile2);
+ ExportContactsL(KVCardFile3,array); //for checking
+ CleanupStack::PopAndDestroy(array);
+ TEST_CONDITION(CountPhoneNumberFieldsL(id)==1);
+
+ CContactItem* item = iDb->ReadContactLC(id);
+ CContactItemFieldSet& fieldSet = item->CardFields();
+ TInt pos=fieldSet.Find(KUidContactFieldPhoneNumber);
+ while (pos!=KErrNotFound)
+ {
+ const CContactItemField& field = (fieldSet)[pos];
+ if (field.Storage()->IsFull())
+ {
+ CContactTextField* textfield = field.TextStorage();
+ _LIT(KExpectedNumber,"4444");
+ TEST_CONDITION(textfield->Text()==KExpectedNumber);
+ }
+ pos=fieldSet.FindNext(KUidContactFieldPhoneNumber,++pos);
+ }
+ CleanupStack::PopAndDestroy(item);
+ }
+
+
+/**
+Case3
+Default number is selected in phone, and same number is edited in PIM.
+After synchronisation edited number is not syncronised at all
+ 1. Choose a phone number field of a phone contact as a default
+ (For example Tel home: 1111)
+ 2. Edit the same number (phone's default) for example
+ home 1111 to 11114444 in PIM
+ 3. Start Synchronisation
+ 4. Default number was not edited in phone. New number was inserted to phone
+ but number was same as the default's number. So, edited number wasn't
+ synchronised at all.
+
+*/
+void CDefaultVoiceParamTests::TestThreeL()
+ {
+ //Not sure how to simulate. I believe this is case is duplicated by TestOneL()
+ }
+
+/*
+Case 4
+Default number is selected in phone, same number is deleted from PIM and new
+number is created in PIM.
+After synchronisation default number is not deleted from PIM but it is duplicated.
+ 1. Choose a phone number field of a phone contact as a default
+ (For example Tel home: 1111)
+ 2. Delete the same number (phone's default) in PIM and create a new number in PIM
+ 3. Start Synchronisation
+ 4. Default is not deleted from PIM. New number is inserted to phone but number is
+ same as default's. Number you created in PIM, is copied correctly to phone.
+
+*/
+void CDefaultVoiceParamTests::TestFourL()
+ {
+ TContactItemId id = CreateItemL(KName,KPhoneNumber);
+
+ CContactIdArray* array = CContactIdArray::NewLC();
+ array->AddL(id);
+ ExportContactsL(KVCardFile1,array);
+ CreateTestDataL(id, KVCardFile2,KModifiedNumberProperty3);
+ ImportContactsL(KVCardFile2);
+ ExportContactsL(KVCardFile3,array); //for checking
+ CleanupStack::PopAndDestroy(array);
+ TEST_CONDITION(CountPhoneNumberFieldsL(id)==1); //no new field was created
+ }
+
+
+/**This checks the contact indentity fields extracted from a known vCard (KTestVcardFile) to ensure
+ the contact is exactly what we expect. This tests both the field value and label in the generated contact.
+ */
+void CDefaultVoiceParamTests::TestFiveL()
+ {
+ CDesCArray* value = new(ELeave) CDesCArrayFlat(KNumberOfExtendedFieldNames);
+ CleanupStack::PushL(value);
+ CDesCArray* label = new(ELeave) CDesCArrayFlat(KNumberOfExtendedFieldNames);
+ CleanupStack::PushL(label);
+
+ for(TInt i=0;i<KNumberOfExtendedFieldNames;i++)
+ {
+ value->AppendL(*((const TDesC*) GNames[i]));
+ label->AppendL(*((const TDesC*) GLabels[i]));
+ }
+ ImportContactsL(KTestVcardFile);
+ const CContactIdArray& list = *iDb->SortedItemsL();
+ CheckCardL(list[0], value, label);
+ CleanupStack::PopAndDestroy(2,value); // + label
+ iDb->DeleteContactL(list[0]);
+ }
+
+/** This generates a whole bunch of conacts (KNumberOfRandomContacts) and exports them to a vCard file.
+ The contacts are then read back in. This tests the merge functionality of vCard parsing.
+ The retrieved cards' fields are checked against the original cards' fields to make sure they're the same */
+void CDefaultVoiceParamTests::TestSixL()
+ {
+ CDesCArray* fields = new(ELeave) CDesC16ArrayFlat(KNumberOfExtendedFieldNames*KNumberOfRandomContacts);
+ CleanupStack::PushL(fields);
+
+ CDesCArray* labels = new(ELeave) CDesC16ArrayFlat(KNumberOfExtendedFieldNames);
+ CleanupStack::PushL(labels);
+ TInt i;
+ for( i=0;i<KNumberOfExtendedFieldNames;i++)
+ {
+ labels->AppendL(*((const TDesC*) GLabels[i]));
+ }
+ RArray<TInt> allIds;
+ CleanupClosePushL(allIds);
+
+ TInt64 randseed = 0;
+ CWordDigrams* firstname = CWordDigrams::NewLC(KFirstNameFileName, randseed);
+ CWordDigrams* lastname = CWordDigrams::NewLC(KLastNameFileName, randseed);
+ CleanupStack::Pop(lastname);
+ CleanupStack::Pop(firstname);
+ CRandomContactGenerator* generator = CRandomContactGenerator::NewL(firstname,lastname );
+
+ CleanupStack::PushL(generator);
+
+ generator->SetDbL(*iDb);
+ RArray<TInt> nameIds;
+ CleanupClosePushL(nameIds);
+ for( i = 0; i<KNumberOfExtendedFieldNames;i++)
+ {
+ nameIds.AppendL(KExtendedFieldNames[i]);
+ }
+
+
+ for ( i = 0;i<KNumberOfRandomContacts;i++)
+ {
+ TContactItemId id = generator->AddTypicalRandomContactWithNamesL(nameIds, ETrue);
+ allIds.AppendL(id);
+ CContactCard* card = STATIC_CAST(CContactCard*, iDb->OpenContactL(id));
+ CleanupStack::PushL(card);
+ CheckCard(card,fields, labels,ECheckLabel|EAppendValue );
+ iDb->CommitContactL(*card);
+ CleanupStack::PopAndDestroy(card);
+ }
+
+ CleanupStack::PopAndDestroy( 2, generator ); // + nameIds
+
+ ExportContactsL(KVCardFile1, iDb->SortedItemsL());
+ ImportContactsL(KVCardFile1);
+
+ for (i =0; i<allIds.Count();i++)
+ {
+ CheckCardL(allIds[i], fields);
+ for(TInt j=0;j<KNumberOfExtendedFieldNames;j++)
+ {
+ fields->Delete(0);
+ }
+ }
+ CleanupStack::PopAndDestroy(3, fields ); // +label
+
+ }
+
+
+/** Import contacts from the vCard file specified by aFileName */
+void CDefaultVoiceParamTests::ImportContactsL(const TDesC& aFileName)
+ {
+ RFileReadStream vcard;
+ User::LeaveIfError(vcard.Open(iTest.Fs(), aFileName, EFileRead));
+ CleanupClosePushL(vcard);
+
+ TBool success=EFalse;
+ CArrayPtr<CContactItem>* contactItems=iDb->ImportContactsL(TUid::Uid(KUidVCardConvDefaultImpl), vcard, success, CContactDatabase::EImportSingleContact+CContactDatabase::ETTFormat);
+ CleanupStack::PopAndDestroy(&vcard);
+ contactItems->ResetAndDestroy();
+ delete contactItems;
+ }
+
+/** Export contact items specified by aIds to aFileName */
+void CDefaultVoiceParamTests::ExportContactsL(const TDesC& aFileName, const CContactIdArray* aIds)
+ {
+ RFile outfile;
+ outfile.Replace(iTest.Fs(),aFileName,EFileWrite);
+ CleanupClosePushL(outfile);
+ RFileWriteStream writeStream(outfile);
+ CleanupClosePushL(writeStream);
+
+ TUid uid;
+ uid.iUid=KUidVCardConvDefaultImpl;
+ iDb->ExportSelectedContactsL(uid,*aIds,writeStream,CContactDatabase::EDefault);
+
+ writeStream.CommitL();
+ CleanupStack::PopAndDestroy(2); //writeStream.Close(), outfile.Close()
+ }
+
+
+/** Creates a vCard with the correct UID for the contact item specified by aId. */
+void CDefaultVoiceParamTests::CreateTestDataL(TContactItemId aId, const TDesC& aFileName, const TDesC8& aVCardData)
+ {
+ RFile file;
+ TInt err=file.Replace(iTest.Fs(), aFileName, EFileWrite+EFileShareAny+EFileStreamText);
+ User::LeaveIfError(err);
+ TPtrC8 header((const TText8*) "BEGIN:VCARD\r\n"
+ "VERSION:2.1\r\n"
+ "REV:20020520T134824Z\r\n"
+ "N:Name;;;;\r\n");
+ TPtrC8 footer((const TText8*) "END:VCARD\r\n");
+ TPtrC8 uidProperty((const TText8*) "UID:");
+ TPtrC8 endProperty((const TText8*) "\r\n");
+ file.Write(header);
+ file.Write(uidProperty);
+ HBufC* buffer = iTest.ContactUidLC(aId,KMachineUniqueId);
+ TBuf8<KMaxExternalizedTokenLength> des;
+ des.Copy(*buffer);
+ file.Write(des);
+ CleanupStack::PopAndDestroy(buffer);
+ file.Write(endProperty);
+ file.Write(aVCardData);
+ file.Write(footer);
+ file.Close();
+ }
+
+/** Count the number of non-empty phone number fields */
+TInt CDefaultVoiceParamTests::CountPhoneNumberFieldsL(TContactItemId aId)
+ {
+ CContactItem* item = iDb->ReadContactLC(aId);
+ CContactItemFieldSet& fieldSet = item->CardFields();
+ TInt numPhoneNumbers=0;
+ TInt pos=fieldSet.Find(KUidContactFieldPhoneNumber);
+ while (pos!=KErrNotFound)
+ {
+ const CContactItemField& field = (fieldSet)[pos];
+ if (field.Storage()->IsFull())
+ numPhoneNumbers++;
+ pos=fieldSet.FindNext(KUidContactFieldPhoneNumber,++pos);
+ }
+ CleanupStack::PopAndDestroy(item);
+ return numPhoneNumbers;
+ }
+
+/** Create a contact item */
+TContactItemId CDefaultVoiceParamTests::CreateItemL(const TDesC& aName, const TDesC& aNumber)
+ {
+ TContactItemId templateId = iDb->TemplateId();
+ CContactItem* templateCard = iDb->ReadContactLC(templateId);
+ CContactCard* card=CContactCard::NewL(templateCard);
+ CleanupStack::PushL(card);
+ SetNameL(*card, KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN, aName, EFalse);
+ SetNameL(*card, KUidContactFieldPhoneNumber,KUidContactFieldVCardMapTEL, aNumber, EFalse);
+ TContactItemId id = iDb->AddNewContactL(*card);
+ CleanupStack::PopAndDestroy(2,templateCard);
+ return id;
+ }
+
+
+/**
+ * Regression testcode for defect EXT-599EF6 "Problems appear when contact's
+ * default number is deleted / edited in PIM - Lotus Organizer 6.0"
+ *
+ * The basic problem is:
+ * SymbianOS uses TEL;VOICE in a vCard to represent a phone number
+ * TimeIS PC Connectivity code sends TEL;VOICE to PIM
+ * PIM removes VOICE property parameter
+ * TimeIS sends TEL back
+ * Contacts model does not match TEL;VOICE and TEL, so a duplicate number is added
+ *
+ */
+LOCAL_C void DefaultVoiceParamTestsL()
+ {
+ CDefaultVoiceParamTests* test = CDefaultVoiceParamTests::NewLC(*CntTest);
+ test->RunTestsL();
+ CleanupStack::PopAndDestroy(test);
+ }
+
+/** Add KNumAccessCountContacts contacts **/
+LOCAL_C void AddNewContactsL()
+ {
+ _LIT(KNameFormat,"NAME #%d");
+ _LIT(KPhoneNumber,"123");
+ for (TInt ii=0;ii<KNumAccessCountContacts;ii++)
+ {
+ CContactCard* card=CContactCard::NewL();
+ CleanupStack::PushL(card);
+ TBuf<16> name;
+ name.Format(KNameFormat,ii);
+ SetNameL(*card, KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN, name, EFalse);
+ SetNameL(*card, KUidContactFieldPhoneNumber,KUidContactFieldVCardMapTEL, KPhoneNumber, EFalse);
+ CntTest->Db()->AddNewContactL(*card);
+ CleanupStack::PopAndDestroy(card);
+ }
+ }
+
+
+LOCAL_C void EmptyDatabase()
+ {
+ TContactItemId theid;
+ TContactIter iter(*CntTest->Db());
+ theid=iter.FirstL();
+ while(theid!=KNullContactId )
+ {
+ CntTest->Db()->DeleteContactL(theid);
+ theid=iter.NextL();
+ }
+ }
+
+
+enum TAccessCountFlags {EIncAccessCount,EDecAccessCount};
+
+LOCAL_C void UpdateAccessCountL(TAccessCountFlags aUpdateType)
+ {
+ TContactItemId theid;
+ TContactIter iter(*CntTest->Db());
+ theid=iter.FirstL();
+ while(theid!=KNullContactId )
+ {
+ CContactItem* contactItem=CntTest->Db()->OpenContactL(theid);
+ CleanupStack::PushL(contactItem);
+ if (contactItem->IsDeleted())
+ test.Next(_L("Synchronizer knows record 2 is deleted"));
+
+ if(aUpdateType==EIncAccessCount)
+ contactItem->IncAccessCount();
+ else
+ contactItem->DecAccessCount();
+
+ theid=iter.NextL();
+ CntTest->Db()->CommitContactL(*contactItem);
+ CleanupStack::PopAndDestroy(contactItem);
+ }
+ }
+
+/** Tests from T_EXPDEL */
+LOCAL_C void AccessCountTestsL()
+ {
+ CContactDatabase* db=CntTest->CreateDatabaseL();
+ AddNewContactsL();
+ TEST_CONDITION(db->CountL()==KNumAccessCountContacts);
+
+ test.Next(_L("Increase Access Count"));
+ UpdateAccessCountL(EIncAccessCount);
+
+ test.Next(_L("Removing second contact"));
+ TContactIter iter(*db);
+ TContactItemId theid=iter.FirstL();
+ theid=iter.NextL();
+ db->DeleteContactL(theid);
+ TEST_CONDITION(db->CountL()==KNumAccessCountContacts-1);
+
+#if defined(_DEBUG) //test case only valid in debug mode, see CContactDatabase::DeletedContactsLC for detail.
+ test.Next(_L("Checking DeletedContactsLC Deleted Count and Identity"));
+ CContactIdArray* delArray = db->DeletedContactsLC();
+ TEST_CONDITION(delArray->Count() == 1); // as second contact is deleted but has access count of > 1
+ TEST_CONDITION((*delArray)[0] == theid); // test the DeletedContact Id is the second Id (that was deleted above)
+
+ CleanupStack::PopAndDestroy(delArray);
+#endif //defined(_DEBUG)
+
+ test.Next(_L("Synchronizing"));
+ UpdateAccessCountL(EDecAccessCount);
+ TEST_CONDITION(db->CountL()==KNumAccessCountContacts-1);
+ test.Next(_L("Exporting"));
+ CContactIdArray* TheIds=CContactIdArray::NewLC();
+ theid=iter.FirstL();
+ while(theid!=KNullContactId )
+ {
+ TheIds->AddL(theid);
+ theid=iter.NextL();
+ }
+ CFileStore* store = CDirectFileStore::ReplaceLC(CntTest->Fs(),KExpDelAFileName(),EFileWrite);
+ store->SetTypeL(KDirectFileStoreLayoutUid);
+ RStoreWriteStream outstream;
+ TStreamId id = outstream.CreateLC(*store);
+ TUid uid;
+ uid.iUid= KVersitEntityUidVCard; // KUidVCardConvDefaultImpl;
+ db->ExportSelectedContactsL(uid,*TheIds,outstream,CContactDatabase::EIncludeX);
+ outstream.CommitL();
+ store->SetRootL(id);
+ store->CommitL();
+ CleanupStack::PopAndDestroy(2); // store+ oustream
+ CleanupStack::PopAndDestroy(TheIds);
+ test.Next(_L("Emptying database"));
+ EmptyDatabase();
+ }
+
+//
+/* Test Function Implementations */
+//
+TContactItemId AddContactL (CContactDatabase& aDatabase)
+ {
+ TInt bit = 0;
+ TContactItemId retval;
+ CRandomContactGenerator* generator = NULL;
+
+ generator = CRandomContactGenerator::NewL();
+ CleanupStack::PushL(generator);
+
+ generator->SetDbL(aDatabase);
+
+ bit |= CContactDatabase::ESmsable;
+ retval = generator->AddTypicalContactForFilterL(bit);
+
+ CleanupStack::PopAndDestroy( generator );
+
+ return retval;
+ }
+
+void ExportContactTestL()
+ {
+ TContactItemId itemId;
+ RFs fsSession;
+ RFileWriteStream fileStream;
+ CContactIdArray* idArray = NULL;
+ CContactItem* contactAdded = NULL;
+ TInt firstNameIndex = KErrNotFound;
+
+ idArray = CContactIdArray::NewL();
+
+ CleanupStack::PushL(idArray);
+
+ User::LeaveIfError(fsSession.Connect());
+ User::LeaveIfError(fileStream.Replace(fsSession, KOutputFileName, EFileWrite));
+
+
+ itemId = AddContactL(*CntTest->Db());
+ contactAdded = CntTest->Db()->OpenContactL(itemId);
+ CleanupStack::PushL(contactAdded);
+
+ CContactItemFieldSet& fieldSet = contactAdded->CardFields();
+
+ firstNameIndex = fieldSet.Find(KUidContactFieldGivenName);
+ TEST_CONDITION(firstNameIndex != KErrNotFound);
+
+ CContactItemField& field = fieldSet[firstNameIndex];
+ field.SetLabelL(_L(" New Label "));
+
+ CntTest->Db()->CommitContactL(*contactAdded);
+ CleanupStack::PopAndDestroy(contactAdded);
+ contactAdded = NULL;
+
+
+ idArray->InsertL(0, itemId);
+
+ CntTest->Db()->ExportSelectedContactsL(TUid::Uid(KUidVCardConvDefaultImpl), *idArray, fileStream, 0 /*option*/);
+ CntTest->Db()->ExportSelectedContactsL(TUid::Uid(KUidVCardConvDefaultImpl), *idArray, fileStream, 1 /*option*/);
+
+ CleanupStack::PopAndDestroy(idArray);
+
+ fileStream.Close();
+ fsSession.Close();
+ }
+
+// Export a contact which has no name field,
+// and check that the exported file doesn't contain a name field:
+void ExportNamelessContactTestL()
+ {
+ TContactItemId itemId;
+ RFs fsSession;
+ RFileWriteStream fileStream;
+ RFileReadStream readStream;
+ CContactIdArray* idArray = NULL;
+ CContactItem* contactAdded = NULL;
+ TInt Index = KErrNotFound;
+
+ idArray = CContactIdArray::NewL();
+
+ CleanupStack::PushL(idArray);
+
+ User::LeaveIfError(fsSession.Connect());
+ User::LeaveIfError(fileStream.Replace(fsSession, KOutputFileName, EFileWrite));
+
+ // Create the usual random contact:
+ itemId = AddContactL(*CntTest->Db());
+ contactAdded = CntTest->Db()->OpenContactL(itemId);
+ CleanupStack::PushL(contactAdded);
+
+ // Find the name fields and remove them:
+ CContactItemFieldSet& fieldSet = contactAdded->CardFields();
+ Index = fieldSet.Find(KUidContactFieldGivenName);
+ if(Index != KErrNotFound)
+ fieldSet.Remove(Index);
+ Index = fieldSet.Find(KUidContactFieldFamilyName);
+ if(Index != KErrNotFound)
+ fieldSet.Remove(Index);
+ Index = fieldSet.Find(KUidContactFieldAdditionalName);
+ if(Index != KErrNotFound)
+ fieldSet.Remove(Index);
+ Index = fieldSet.Find(KUidContactFieldPrefixName);
+ if(Index != KErrNotFound)
+ fieldSet.Remove(Index);
+ Index = fieldSet.Find(KUidContactFieldSuffixName);
+ if(Index != KErrNotFound)
+ fieldSet.Remove(Index);
+
+ // Put the contact back:
+ CntTest->Db()->CommitContactL(*contactAdded);
+ CleanupStack::PopAndDestroy(contactAdded);
+ contactAdded = NULL;
+
+ // Export it:
+ idArray->InsertL(0, itemId);
+ CntTest->Db()->ExportSelectedContactsL(TUid::Uid(KUidVCardConvDefaultImpl), *idArray, fileStream, 0 /*option*/);
+ CleanupStack::PopAndDestroy(idArray);
+ fileStream.Close();
+
+ // Verify the output by reading it in and searching it long hand:
+ User::LeaveIfError(readStream.Open(fsSession, KOutputFileName, EFileRead));
+ HBufC8 * buf = HBufC8::NewLC(100);
+ TPtr8 ptr = buf->Des();
+ TRAPD(ret, readStream.ReadL(ptr));
+ TEST_CONDITION(ret == KErrNone || (ret == KErrEof && buf->Length() > 0));
+
+ // This is the important test - we should not find a name entry:
+ _LIT8(str, "\nN:");
+ TEST_CONDITION(buf->Find(str) == KErrNotFound);
+
+ // Clean up:
+ CleanupStack::PopAndDestroy(buf);
+
+ readStream.Close();
+ fsSession.Close();
+ }
+
+//=======================================================================
+//FindInFields
+//Finds a given value in the field set, assumes that the fields are text.
+//Used by CheckTypeSupport.
+//=======================================================================
+TBool FindInFields(CContactItemFieldSet& aFieldSet,TPtrC aExpectedValue)
+ {
+ for (TInt i = 0; i< aFieldSet.Count(); i++ )
+ {
+ CContactItemField& aFieldValue = aFieldSet[i];
+ TPtrC value = aFieldValue.TextStorage()->Text();
+ if (value == aExpectedValue)
+ {
+ return ETrue;
+ }
+ }
+
+ // Value not found, return false.
+ return EFalse;
+ }
+
+//=======================================================================
+//FieldCheck
+//Compares the value of the CContactItemField at aIndex of aFieldSet
+//with the expected value. Used by UpdateVCardTestL
+//=======================================================================
+TBool FieldCheck(CContactItemFieldSet& aFieldSet,TInt aIndex,TPtrC aExpectedValue)
+ {
+ CContactItemField& aPhoneNum = aFieldSet[aIndex];
+ TPtrC value = aPhoneNum.TextStorage()->Text();
+ return (value == aExpectedValue);
+ }
+//=======================================================================
+//UpdateVCardTestL()
+//Checks updating of a contact via a modified vcard.
+//1: Contact is imported from vcardupdate1.vcf
+//2: Contact is exported to vcardupdate2.vcf
+//3: Contact is updated from vcardupdate3.vcf
+//=======================================================================
+void UpdateVCardTestL()
+ {
+ test.Next(_L("Update VCard Test"));
+ //Check the database is empty before we start
+ EmptyDatabase();
+ TInt count = CntTest->Db()->CountL();
+ TEST_CONDITION(count == 0);
+ test.Next(_L("Database Empty"));
+
+ RFs fsSession;
+ User::LeaveIfError(fsSession.Connect());
+
+ RFileReadStream readStream;
+ RFileWriteStream writeStream;
+ CContactIdArray* idArray = NULL;
+
+ idArray = CContactIdArray::NewL();
+ CleanupStack::PushL(idArray);
+
+ //Import vcardupdate1.vcf
+ test.Next(_L("Importing contact from vcardupdate1.vcf"));
+ User::LeaveIfError(readStream.Open(fsSession,KVCardUpdate1, EFileRead));
+ CleanupClosePushL(readStream);
+ TBool success=EFalse;
+ CArrayPtr<CContactItem>* contactItems=CntTest->Db()->ImportContactsL(TUid::Uid(KUidVCardConvDefaultImpl), readStream, success, CContactDatabase::EImportSingleContact+CContactDatabase::ETTFormat);
+ //Store the id of the new contact - we need this later
+ TContactItemId contactId = (*contactItems)[0]->Id();
+ idArray->InsertL(0, contactId);
+ readStream.Close();
+ //Should be the only contact in the database at this point
+ count = CntTest->Db()->CountL();
+ TEST_CONDITION(count == 1);
+ test.Next(_L("Imported"));
+
+ //Retrieve the new contact from the database and check the fields
+ CContactItem* importedContact = CntTest->Db()->ReadContactLC(contactId);
+ CContactItemFieldSet& importedContactFieldSet = importedContact->CardFields();
+
+ /*
+ * For this particular test we are only interested in the following field indexes:
+ * 5: Mobile 1
+ * 6: Mobile 2
+ * 29: Work tel 1
+ * 30: Work tel 2
+ * 31: Work tel 3
+ * 32: Work tel 4
+ * 33: Work tel 5
+ * You can get other field indexes by using:
+ *
+ _LIT(KFormat,"%d:\t");
+ for (TInt i = 0; i < importedContactFieldSet.Count();i++)
+ {
+ CContactItemField& aPhoneNum = importedContactFieldSet[i];
+ TPtrC label = aPhoneNum.Label();
+ test.Printf(KFormat,i);
+ test.Printf(label);
+ }
+ */
+
+ test.Next(_L("Check Mobile Number 1"));
+ TEST_CONDITION(FieldCheck(importedContactFieldSet,5,_L("07905111")));
+
+ test.Next(_L("Check Mobile Number 2"));
+ TEST_CONDITION(FieldCheck(importedContactFieldSet,6,_L("07906222")));
+
+ test.Next(_L("Check Work Number 1"));
+ TEST_CONDITION(FieldCheck(importedContactFieldSet,29,_L("1111111111")));
+
+ test.Next(_L("Check Work Number 2"));
+ TEST_CONDITION(FieldCheck(importedContactFieldSet,30,_L("2222222222")));
+
+ test.Next(_L("Check Work Number 3"));
+ TEST_CONDITION(FieldCheck(importedContactFieldSet,31,_L("3333333333")));
+
+ test.Next(_L("Check Work Number 4"));
+ TEST_CONDITION(FieldCheck(importedContactFieldSet,32,_L("4444444444")));
+
+ test.Next(_L("Check Work Number 5"));
+ TEST_CONDITION(FieldCheck(importedContactFieldSet,33,_L("5555555555")));
+
+ CleanupStack::PopAndDestroy(importedContact);
+
+ //Export the contact to vcardupdate2.vcf
+ test.Next(_L("Exporting contact to vcardupdate2.vcf"));
+ User::LeaveIfError(writeStream.Replace(fsSession,KVCardUpdate2,EFileWrite));
+ CleanupClosePushL(writeStream);
+ CntTest->Db()->ExportSelectedContactsL(TUid::Uid(KUidVCardConvDefaultImpl), *idArray, writeStream,0);
+ CleanupStack::PopAndDestroy(&writeStream);
+
+ //Import vcardupdate3.vcf - this should have the same UID as vcardupdate2.vcf
+ test.Next(_L("Updating contact from vcardupdate3.vcf"));
+ User::LeaveIfError(readStream.Open(fsSession,KVCardUpdate3, EFileRead));
+ success=EFalse;
+ contactItems->ResetAndDestroy();
+ delete contactItems;
+ contactItems = CntTest->Db()->ImportContactsL(TUid::Uid(KUidVCardConvDefaultImpl), readStream, success, CContactDatabase::EImportSingleContact+CContactDatabase::ETTFormat);
+
+ //We are updating the previous contact so we should still only have
+ //one database entry. If count == 2 here check the uids of C:\\vcardupdate2.vcf and
+ //Z:\\System\\Programs\\CntmodelTest\\vcardupdate3.vcf - the last digits of vcardupdate3 should match vcardupdate2
+ count = CntTest->Db()->CountL();
+ //TEST_CONDITION(count == 1);
+ test.Next(_L("Imported"));
+
+ //Retrieve the updated contact from the database and check the fields
+ //Use the same contact id as before
+ CContactItem* updatedContact = CntTest->Db()->ReadContactLC(contactId);
+ CContactItemFieldSet& updatedContactFieldSet = updatedContact->CardFields();
+
+ test.Next(_L("Check Updated Mobile Number 1"));
+ TEST_CONDITION(FieldCheck(updatedContactFieldSet,5,_L("7700900329")));
+
+ test.Next(_L("Check Updated Mobile Number 2"));
+ TEST_CONDITION(FieldCheck(updatedContactFieldSet,6,_L("07700900529")));
+
+ test.Next(_L("Check Updated Work Number 1"));
+ TEST_CONDITION(FieldCheck(updatedContactFieldSet,29,_L("7700900999")));
+
+ test.Next(_L("Check Updated Work Number 2"));
+ TEST_CONDITION(FieldCheck(updatedContactFieldSet,30,_L("7700900888")));
+
+ test.Next(_L("Check Updated Work Number 3"));
+ TEST_CONDITION(FieldCheck(updatedContactFieldSet,31,_L("7700900777")));
+
+ test.Next(_L("Check Updated Work Number 4"));
+ TEST_CONDITION(FieldCheck(updatedContactFieldSet,32,_L("7700900666")));
+
+ test.Next(_L("Check Updated Work Number 5"));
+ TEST_CONDITION(FieldCheck(updatedContactFieldSet,33,_L("7700900555")));
+
+ //cleanup
+ CleanupStack::PopAndDestroy(updatedContact);
+ CleanupStack::PopAndDestroy(&readStream);
+ CleanupStack::PopAndDestroy(idArray);
+ fsSession.Close();
+ contactItems->ResetAndDestroy();
+ delete contactItems;
+ }
+
+/*
+The following is the test for trailing space to test DEF051853.
+*/
+
+const TUint KSpaceChar = 0x20;
+
+_LIT( KSearchText, "\x2029" );
+_LIT( KIncommingVCard, "z:\\cntvcard\\address-with-trailing-white-space.vcf" );
+_LIT( KOutgoingVCard, "c:\\address-with-trailing-white-space-out.vcf" );
+
+/** Import contacts from the vCard file specified by aFileName */
+CArrayPtr<CContactItem>* ImportContactsL(const TDesC& aFileName, CContactDatabase& aDatabase);
+void CheckForWhiteSpaceL( const TDesC& aFieldToCheck );
+void ImportAndCheckForNoTrailSpaceStrippingL(const TDesC& aFileName, CContactIdArray& aArray);
+void TrailingSpaceExportContactsL(const TDesC& aFileName, CContactIdArray* aIds);
+void DoTrailingSpaceImportAndExportTestL();
+
+// Implementations
+CArrayPtr<CContactItem>* ImportContactsL(const TDesC& aFileName, CContactDatabase& aDatabase)
+ {
+ CArrayPtr<CContactItem>* retval = NULL;
+ RFileReadStream vcard;
+ RFs fileSystem;
+ User::LeaveIfError( fileSystem.Connect() );
+ CleanupClosePushL( fileSystem );
+ User::LeaveIfError(vcard.Open( fileSystem, aFileName, EFileRead));
+ CleanupClosePushL(vcard);
+
+ TBool success=EFalse;
+ retval = aDatabase.ImportContactsL(TUid::Uid(KVersitEntityUidVCard), vcard, success, CContactDatabase::EImportSingleContact+CContactDatabase::ETTFormat);
+ CleanupStack::PopAndDestroy(&vcard);
+ CleanupStack::PopAndDestroy(&fileSystem);
+
+ return retval;
+ }
+
+void CheckForWhiteSpaceL( const TDesC& aFieldToCheck )
+ {
+ TInt trailingSpaceLocation = KErrNotFound;
+ TUint thisShouldBeASpaceChar = 0;
+
+ trailingSpaceLocation = ( aFieldToCheck.Find(KSearchText) -1 );
+
+ thisShouldBeASpaceChar = aFieldToCheck[ trailingSpaceLocation ];
+ test ( thisShouldBeASpaceChar == KSpaceChar );
+
+ }
+
+void ImportAndCheckForNoTrailSpaceStrippingL(const TDesC& aFileName, CContactIdArray& aArray)
+ {
+ CArrayPtr<CContactItem>* contactList = NULL;
+ CContactItem* item = NULL;
+ TInt addressIndex = KErrNotFound;
+
+ aArray.Reset();
+
+ contactList = ImportContactsL( aFileName, *CntTest->Db() );
+ CleanupStack::PushL( contactList );
+
+ item = (*contactList)[0];
+ aArray.AddL( item->Id() );
+ CContactItemFieldSet& fieldSet = item->CardFields();
+
+ addressIndex = fieldSet.Find( KUidContactFieldAddress );
+
+ CContactItemField& addressField = fieldSet[ addressIndex ];
+
+
+ TPtrC data = addressField.TextStorage()->Text();
+
+ CheckForWhiteSpaceL( data );
+
+ contactList->ResetAndDestroy();
+ CleanupStack::PopAndDestroy( contactList );
+
+ }
+
+/** Export contact items specified by aIds to aFileName */
+void TrailingSpaceExportContactsL(const TDesC& aFileName, CContactIdArray* aIds)
+ {
+ RFs fsSession;
+ RFileWriteStream fileStream;
+
+ User::LeaveIfError(fsSession.Connect());
+ User::LeaveIfError(fileStream.Replace(fsSession, aFileName, EFileWrite));
+
+ CntTest->Db()->ExportSelectedContactsL(TUid::Uid(KVersitEntityUidVCard), *aIds, fileStream, 0 /*option*/);
+
+ fileStream.Close();
+ fsSession.Close();
+
+ }
+
+
+void DoTrailingSpaceImportAndExportTestL()
+ {
+ CContactIdArray* idArray = NULL;
+
+ idArray = CContactIdArray::NewL();
+ CleanupStack::PushL( idArray );
+
+ ImportAndCheckForNoTrailSpaceStrippingL(KIncommingVCard, *idArray);
+ TrailingSpaceExportContactsL( KOutgoingVCard, idArray );
+
+ ImportAndCheckForNoTrailSpaceStrippingL(KOutgoingVCard, *idArray);
+ CleanupStack::PopAndDestroy( idArray );
+ }
+
+
+void ImportLargeVCardTestL()
+ {
+ test.Printf(_L("Importing large VCards"));
+
+ EmptyDatabase();
+
+ RFs fsSession;
+ User::LeaveIfError(fsSession.Connect());
+
+ RFileReadStream readStream;
+
+ // Import vcardupdate1.vcf.
+ test.Printf(_L("Importing contact from testvcard1.vcf"));
+ User::LeaveIfError(readStream.Open(fsSession,KTestVcardFile1, EFileRead));
+
+ CleanupClosePushL(readStream);
+
+ TBool success=EFalse;
+ CArrayPtr<CContactItem>* contactItems=CntTest->Db()->ImportContactsL(
+ TUid::Uid(KUidVCardConvDefaultImpl), readStream, success,
+ CContactDatabase::EImportSingleContact+CContactDatabase::ETTFormat);
+
+ // If the above function does not leave or panic test has been successful.
+
+ TEST_CONDITION(contactItems->Count() == 1);
+
+ test.Printf(_L("Importing large VCards successful\n"));
+
+ contactItems->ResetAndDestroy();
+ delete contactItems;
+
+ CleanupStack::PopAndDestroy(&readStream);
+
+ fsSession.Close();
+ }
+
+
+//return the number of email fields within a contact
+TInt ContactEmailCountL(TContactItemId aContactId)
+ {
+
+ CContactItem *item = CntTest->Db()->ReadContactLC(aContactId);
+ TInt pos = 0;
+ TInt many = 0;
+ while (pos < item->CardFields().Count() )
+ {
+ pos = item->CardFields().FindNext(KUidContactFieldEMail, pos);
+ if( pos == KErrNotFound )
+ {
+ break;
+ }
+ else
+ {
+ ++many;
+ ++pos;
+ }
+ }
+
+ CleanupStack::PopAndDestroy(item);
+ return many;
+
+ }
+
+//import a single contact item from vcard into db, return id of contact in db
+TContactItemId ImportVCardL(const TDesC &aVcard, const TInt aOption)
+ {
+ RFs fsSession;
+ User::LeaveIfError(fsSession.Connect());
+
+ RFileReadStream readStream;
+
+ //Import vcf
+ User::LeaveIfError(readStream.Open(fsSession,aVcard, EFileRead));
+ CleanupClosePushL(readStream);
+ TBool success=EFalse;
+ CArrayPtr<CContactItem>* contactItems = CntTest->Db()->ImportContactsL(
+ TUid::Uid(KVersitEntityUidVCard), readStream, success,
+ aOption
+ );
+
+ //Store the id of the new contact - we need this later
+ TContactItemId contactId = (*contactItems)[0]->Id();
+ contactItems->ResetAndDestroy();
+ delete contactItems;
+ contactItems = NULL;
+ //cleanup
+ CleanupStack::PopAndDestroy(&readStream);
+ fsSession.Close();
+ return contactId;
+ }
+
+//returns the number of non empty fields in contact
+TInt ContactFilledFields(TContactItemId aContactId)
+ {
+ CContactItem *item = CntTest->Db()->ReadMinimalContactLC(aContactId);
+ TInt ret = item->CardFields().Count();
+ CleanupStack::PopAndDestroy(item);
+ return ret;
+ }
+
+/**
+@SYMTestCaseID PIM-T-CNTVCARD-DEF084708-0001
+@SYMTestType UT
+@SYMTestPriority High
+@SYMDEF DEF084708
+@SYMTestCaseDesc Vcard with full parameter description of TYPE=VALUE for properties
+ADDR or TEL should be correctly imported.
+
+@SYMTestActions
+1) import vcard with home and tel properties with parameters of TYPE=HOME and TYPE=WORK
+2) check that imported contact contains the correct home and work address
+
+@SYMTestExpectedResults For the above tests:
+On importing, the type=home and type=work fields should not be deleted.
+
+*/
+void CheckTypeSupport(const TDesC &inputVcard)
+{
+ test.Next(_L("@SYMTestCaseID:PIM-T-CNTVCARD-DEF084708-0001 Checking if the type=value parameter is handled correctly."));
+
+ //Check the database is empty before we start
+ EmptyDatabase();
+ TInt count = CntTest->Db()->CountL();
+ TEST_CONDITION(count == 0);
+
+ // First import the vcard file.
+ RFs fsSession;
+ RFileReadStream readStream;
+ User::LeaveIfError(fsSession.Connect());
+ test.Printf(_L("Importing contact "));
+ User::LeaveIfError(readStream.Open(fsSession,inputVcard, EFileRead));
+ CleanupClosePushL(readStream);
+ TBool success=EFalse;
+ CArrayPtr<CContactItem>* contactItems=CntTest->Db()->ImportContactsL(TUid::Uid(KUidVCardConvDefaultImpl), readStream, success, CContactDatabase::EImportSingleContact+CContactDatabase::ETTFormat);
+ readStream.Close();
+
+ //Should be the only contact in the database at this point
+ count = CntTest->Db()->CountL();
+ TEST_CONDITION(count == 1);
+ test.Printf(_L("Imported the contact item"));
+
+ // Check that the home address and work address has been imported correctly into the card.
+ test.Printf(_L("Find whether all the address fields are present."));
+ TContactItemId contactId = (*contactItems)[0]->Id();
+ CContactItem* importedContact = CntTest->Db()->ReadContactLC(contactId);
+ CContactItemFieldSet& fieldSet = importedContact->CardFields();
+
+ TEST_CONDITION(FindInFields(fieldSet, _L("W211")));
+ TEST_CONDITION(FindInFields(fieldSet, _L("W212")));
+ TEST_CONDITION(FindInFields(fieldSet, _L("W213")));
+ TEST_CONDITION(FindInFields(fieldSet, _L("W214")));
+ TEST_CONDITION(FindInFields(fieldSet, _L("W215")));
+
+ TEST_CONDITION(FindInFields(fieldSet, _L("H211")));
+ TEST_CONDITION(FindInFields(fieldSet, _L("H212")));
+ TEST_CONDITION(FindInFields(fieldSet, _L("H213")));
+ TEST_CONDITION(FindInFields(fieldSet, _L("H214")));
+ TEST_CONDITION(FindInFields(fieldSet, _L("H215")));
+
+ // Check that the phone number has been correctly imported
+ TEST_CONDITION(FindInFields(fieldSet, _L("222222222222222222")));
+ TEST_CONDITION(FindInFields(fieldSet, _L("333333333333333333")));
+
+ //cleanup
+ CleanupStack::PopAndDestroy(importedContact);
+ CleanupStack::PopAndDestroy(&readStream);
+ fsSession.Close();
+ contactItems->ResetAndDestroy();
+ delete contactItems;
+}
+
+/**
+@SYMTestCaseID PIM-T-CNTVCARD-DEF081712-0001
+@SYMTestType UT
+@SYMTestPriority High
+@SYMDEF DEF081712
+@SYMTestCaseDesc Contact properties on device not deleted during synchronisation
+
+@SYMTestActions
+1) import vcard with 3 emails
+2) check that imported contact contains 3 email fields
+3) update uid of imported contact to 8
+4) import vcard with no email fields and uid 8
+5) check that all email fields are deleted
+6) check that no other fields have been deleted
+
+@SYMTestExpectedResults For the above tests:
+It should be possible to delete multiple fields of the same type when a vcard is imported
+*/
+
+void VCardEmailTestL()
+ {
+ const TInt importOption =
+ CContactDatabase::ELocalTime |
+ CContactDatabase::EImportSingleContact |
+ CContactDatabase::ENullTemplateId;
+
+ test.Next(_L("@SYMTestCaseID:PIM-T-CNTVCARD-DEF081712-0001 VCard Email Test"));
+ //start with fresh/clean database
+ CntTest->CreateDatabaseL();
+ TInt count = CntTest->Db()->CountL();
+ TEST_CONDITION(count == 0);
+
+ test.Next(_L("Importing initial contact from 1.vcf"));
+ TContactItemId contactId = ImportVCardL( KVcard1, importOption );
+ TInt initialcount = ContactFilledFields(contactId);
+
+ count = CntTest->Db()->CountL();
+ TEST_CONDITION(count == 1);
+
+ CContactItem *item = CntTest->Db()->OpenContactLX(contactId);
+ CleanupStack::PushL( item );
+
+ _LIT(guid, "8");
+ item->SetUidStringL( const_cast<TDesC &>( guid() ) );
+ CntTest->Db()->CommitContactL( *item );
+ CleanupStack::PopAndDestroy(item);
+ CleanupStack::Pop();//lock
+ item = NULL;
+
+ test.Next(_L("check number of email fields"));
+ TEST_CONDITION(ContactEmailCountL(contactId) == 3);
+
+ test.Next(_L("reimport contact from 2.vcf"));
+ contactId = ImportVCardL( KVcard2, importOption );
+ count = CntTest->Db()->CountL();
+ TEST_CONDITION(count == 1);
+
+ TInt updatedcount = ContactFilledFields(contactId);
+
+ test.Next(_L("check email fields are deleted"));
+ TEST_CONDITION(ContactEmailCountL(contactId) == 0);
+
+ test.Next(_L("check no other fields are cleared or deleted"));
+ TEST_CONDITION( updatedcount == (initialcount - 3) );
+
+ }
+
+/**
+@SYMTestCaseID PIM-T-CNTVCARD-DEF083613-0001
+@SYMTestType UT
+@SYMTestPriority High
+@SYMDEF DEF083613
+@SYMTestCaseDesc A VCard with lines terminated by LF(line-feed)s only is not imported correctly.
+
+@SYMTestActions
+1) import a vcard containing only line-feed line terminators.
+2) Check that the import was successful.
+
+@SYMTestExpectedResults The vcard containing only LF line terminators is imported correctly.
+*/
+
+void VCardLineFeedOnlyTestL()
+ {
+ const TInt importOption =
+ CContactDatabase::ELocalTime |
+ CContactDatabase::EImportSingleContact |
+ CContactDatabase::ENullTemplateId;
+
+ TRAPD(err, ImportVCardL( KVCardFileLF, importOption ));
+ TEST_CONDITION(err==0);
+ }
+/**
+@SYMTestCaseID PIM-T-CNTVCARD-DEF085873-0001
+@SYMTestType UT
+@SYMTestPriority High
+@SYMDEF DEF085873
+@SYMTestCaseDesc Check that use of the CContactVCardConverter::EIgnoreUid flag
+behaves correctly.
+
+@SYMTestActions
+1) Empty database.
+2) Import a vcard containing a UID without using the flag.
+3) Check there is only one contact in the database.
+4) Import the same vcard without using the flag. The import should count as an
+update of the existing contact item.
+5) Check there is only one contact in the database.
+6) Import the same vcard using the flag. The import should count as an add of
+a new item.
+7) Check there are now 2 contacts in the database.
+
+@SYMTestExpectedResults The vcard is added to the database a second time when
+the CContactVCardConverter::EIgnoreUid flag is used.
+*/
+void VCardIgnoreUidTestL()
+ {
+ const TInt importOption1 = CContactDatabase::ELocalTime;
+
+ const TInt importOption2 =
+ CContactDatabase::ELocalTime |
+ CContactVCardConverter::EIgnoreUid;
+
+ test.Next(_L("@SYMTestCaseID:PIM-T-CNTVCARD-DEF085873-0001 Check that use of the CContactVCardConverter::EIgnoreUid flag behaves correctly."));
+
+ // 1) Empty database.
+ EmptyDatabase();
+ TInt count = CntTest->Db()->CountL();
+ TEST_CONDITION(count == 0);
+
+ // 2) Import a vcard containing a UID without using the flag.
+ TRAPD(err, ImportVCardL( KVCardFileUID, importOption1 ));
+ TEST_CONDITION(err==0);
+
+ // 3) Check there is only one contact in the database.
+ count = CntTest->Db()->CountL();
+ TEST_CONDITION(count == 1);
+
+ // 4) Import the same vcard without using the flag. The import should count
+ // as an update of the existing contact item.
+ TRAP(err, ImportVCardL( KVCardFileUID, importOption1 ));
+ TEST_CONDITION(err==0);
+
+ // 5) Check there is only one contact in the database.
+ count = CntTest->Db()->CountL();
+ TEST_CONDITION(count == 1);
+
+ // 6) Import the same vcard using the flag. The import should count as an
+ // add of a new item.
+ TRAP(err, ImportVCardL( KVCardFileUID, importOption2 ));
+ TEST_CONDITION(err==0);
+
+ // 7) Check there are now 2 contacts in the database.
+ count = CntTest->Db()->CountL();
+ TEST_CONDITION(count == 2);
+ }
+/*@SYMTestPriority High
+@SYMDEF PDEF097999
+@SYMTestCaseDesc The identity table is not updated if we pass a null value for
+updation (as a result sorting goes wrong)
+@SYMTestActions
+1) Import a vcard containing firstname and lastname.
+2) Import the same vcf file but without having lastname for one entry
+3) Check whether the old lastname is present for that entry.
+
+@SYMTestExpectedResults The identity table must be updated even if we give a null value for lastname.
+so if we search for the old lastname it should not be there .
+*/
+LOCAL_C void TestImportContactsL(const TDesC& aFileName1 , const TDesC& aFileName2 , const TDesC8& aVcfData1 , const TDesC8& aVcfData2)
+ {
+ test.Next(_L("checking Updation of Identity table"));
+ CContactDatabase *db=CntTest->CreateDatabaseL();
+
+ RFs fileSystem;
+ User::LeaveIfError( fileSystem.Connect() );
+ CleanupClosePushL( fileSystem );
+ //Creating input Vcf files
+ RFile file;
+ file.Replace(fileSystem, aFileName1, EFileWrite+EFileShareAny+EFileStreamText);
+ file.Write(aVcfData1);
+ file.Close();
+
+ file.Replace(fileSystem, aFileName2, EFileWrite+EFileShareAny+EFileStreamText);
+ file.Write(aVcfData2);
+ file.Close();
+
+ RFileReadStream vcard;
+ User::LeaveIfError(vcard.Open(fileSystem, aFileName1, EFileRead));
+ CleanupClosePushL(vcard);
+ TBool success=EFalse;
+ CArrayPtr<CContactItem>* contactItems=db->ImportContactsL(TUid::Uid(KUidVCardConvDefaultImpl), vcard, success, CContactDatabase::ETTFormat);
+ CleanupStack::PopAndDestroy(&vcard);
+ contactItems->ResetAndDestroy();
+ delete contactItems;
+
+ User::LeaveIfError(vcard.Open(fileSystem, aFileName2, EFileRead));
+ CleanupClosePushL(vcard);
+ success=EFalse;
+ contactItems=db->ImportContactsL(TUid::Uid(KUidVCardConvDefaultImpl), vcard, success, CContactDatabase::ETTFormat);
+ CleanupStack::PopAndDestroy(&vcard);
+
+ //Search for "Bbb" it must not be there
+ CContactItemFieldDef* fieldDef = new(ELeave) CContactItemFieldDef;
+ TFieldType fieldtype = KUidContactFieldFamilyName;
+ fieldDef->AppendL(fieldtype);
+ CContactIdArray* matchList = db->FindLC(_L("Bbb"), fieldDef);
+ TInt matchCount = matchList->Count();
+ //Count zero means the vcard has been updated properly
+ TEST_CONDITION(matchCount==0);
+ test.Printf (_L("Sucessfully modified identity table"));
+ CleanupStack::PopAndDestroy(matchList);
+ contactItems->ResetAndDestroy();
+ delete contactItems;
+ delete fieldDef;
+ CntTest->CloseDatabase();
+ CleanupStack::PopAndDestroy(&fileSystem);
+ }
+
+ CArrayPtr<CContactItem>* ImportContactsL(const TDesC8& aImportFileInputDescriptor, CContactDatabase* aDatabase)
+ {
+ CArrayPtr<CContactItem>* retval = NULL;
+
+ // read the input contents
+ RDesReadStream vCard(aImportFileInputDescriptor);
+ CleanupClosePushL(vCard);
+
+ //import
+ TBool success=EFalse;
+ retval = aDatabase->ImportContactsL(TUid::Uid(KUidVCardConvDefaultImpl), vCard, success, CContactDatabase::EDefault);
+
+ CleanupStack::PopAndDestroy(&vCard);
+ return retval;
+ }
+
+void TestStorageType( CContactItem *aContactItem, TStorageType aExpectedStorageType)
+ {
+ //verify test
+ TInt fieldIndex = aContactItem->CardFields().Find(KUidContactFieldVCardMapKEY);
+ TStorageType storageType = aContactItem->CardFields()[fieldIndex].StorageType();
+ TEST_CONDITION(storageType == aExpectedStorageType);
+ test.Next(_L("ImportExportVCardWithKeyL passed"));
+ }
+
+ /**
+ @SYMTestCaseID PIM-T-CNTVCARD-DEF097565-0001
+ @SYMTestType UT
+ @SYMTestPriority Medium
+ @SYMDEF DEF097565
+ @SYMTestCaseDesc Importr the vcf file and then check whether the BInary Key is imported
+ properly or not.
+
+ @SYMTestActions
+ 1) Create an empty database.
+ 2) Import a vcard.
+ 3) Check there is Key field imported is having storage type KStorageTypeStore.
+
+ @SYMTestExpectedResults The vcard is containing the Binary Key value.
+ */
+ void ImportExportVCardWithKeyL(const TDesC8& aImportFileInputDescriptor, TStorageType aExpectedStorageType)
+ {
+ test.Next(_L("@SYMTestCaseID:PIM-T-CNTVCARD-DEF097565-0001 ImportExportVCardWithKeyL Begins"));
+
+ CntTest->CreateDatabaseL();
+
+ //import
+ CArrayPtr <CContactItem>* contactItems = NULL;
+ contactItems = ImportContactsL(aImportFileInputDescriptor, CntTest->Db());
+
+ //verify test
+ TestStorageType((contactItems->At(0)), aExpectedStorageType);
+
+ // reclaim memory
+ contactItems->ResetAndDestroy() ;
+ delete contactItems;
+
+ CntTest->CloseDatabase();
+ }
+/**
+@SYMTestCaseID PIM-T-CNTVCARD-INC096705-0001
+@SYMTestType UT
+@SYMTestPriority Medium
+@SYMDEF INC096705
+@SYMTestCaseDesc Check that use of the CContactVCardConverter::EReplaceIfExists flag
+behaves correctly.
+
+@SYMTestActions
+1) Empty database.
+2) Import a vcard containing a company field with EDefault flag.
+3) Check of company field is imported
+4) Import the same vcard without company field and using CContactVCardConverter::EReplaceIfExists option
+
+@SYMTestExpectedResults The vcard is replaced with the contact in the database when
+the CContactVCardConverter::EReplaceIfExists flag is used.
+*/
+void ImportVCardWithFlagReplaceIfExitstL()
+{
+ CContactDatabase *db=CntTest->CreateDatabaseL();
+ test.Next(_L("@SYMTestCaseID:PIM-T-CNTVCARD-INC096705-0001 hecking Replacing old contact with new one"));
+ const TInt importOption1 = CContactDatabase::EDefault;
+ const TInt importOption2 = CContactDatabase::EConverterReserved2;
+
+ // 1) Empty database.
+ EmptyDatabase();
+ TInt count = db->CountL();
+ TEST_CONDITION(count == 0);
+
+ // 2) Import a vcard containing company filed with CContactDatabase::EDefault flag.
+ // and ensure company field gets imported
+ test.Next(_L("Importing Contact with Company field"));
+ TContactItemId aContactId = ImportVCardL( KVCardWithCompany, importOption1 );
+ CContactItem *item = db->ReadContactLC(aContactId);
+ CContactItemFieldSet& fieldSet = item->CardFields();
+ TInt companyIndex = fieldSet.Find( KUidContactFieldCompanyName );
+ TEST_CONDITION(companyIndex != KErrNotFound );
+ const CContactItemField& field = (fieldSet)[companyIndex];
+ TEST_CONDITION(field.Storage()->IsFull() != 0);
+ CContactTextField* textfield = field.TextStorage();
+ _LIT(KExpectedNumber,"XYZ ltd");
+ TEST_CONDITION(textfield->Text()==KExpectedNumber);
+ CleanupStack::PopAndDestroy(item);
+
+ //3)Import a vcard without containing company filed with CContactDatabase::EDefault flag.
+ // and ensure company field gets merged
+ test.Next(_L("Importing Same Contact and merging the old contact without company field"));
+ TContactItemId aContactId1 = ImportVCardL( KVCardWithoutCompany, importOption1 );
+
+ //4) Ensure that company field should be there
+ CContactItem *item1 = db->ReadContactLC(aContactId1);
+ CContactItemFieldSet& fieldSet1 = item1->CardFields();
+ TInt companyIndex1 = fieldSet1.Find( KUidContactFieldCompanyName );
+ TEST_CONDITION(companyIndex1 != KErrNotFound );
+ const CContactItemField& field1 = (fieldSet1)[companyIndex1];
+ TEST_CONDITION(field1.Storage()->IsFull() != 0);
+ CContactTextField* textfield1 = field1.TextStorage();
+ _LIT(KExpectedNumber1,"XYZ ltd");
+ TEST_CONDITION(textfield1->Text()==KExpectedNumber1);
+
+ CleanupStack::PopAndDestroy(item1);
+
+ //5) Import the same vcard without company field and using CContactVCardConverter::EReplaceIfExists option
+ test.Next(_L("Importing Same Contact and replacing with the old contact without company field"));
+ TContactItemId aContactId2 = ImportVCardL( KVCardWithoutCompany, importOption2 );
+
+ //6) Ensure that company field should not be there
+ CContactItem *item2 = db->ReadContactLC(aContactId2);
+ CContactItemFieldSet& fieldSet2 = item2->CardFields();
+ TInt companyIndex2 = fieldSet2.Find( KUidContactFieldCompanyName );
+ const CContactItemField& field2 = (fieldSet2)[companyIndex2];
+ TEST_CONDITION(field2.Storage()->IsFull() == 0);
+ CleanupStack::PopAndDestroy(item2);
+}
+
+ /**
+ @SYMTestCaseID PIM-T-CNTVCARD-INC110795-0001
+ @SYMTestType UT
+ @SYMTestPriority Medium
+ @SYMDEF INC110795
+ @SYMTestCaseDesc Check the use of import option with CContactVCardConverter::EReplaceIfExists flag
+ behaves correctly with duplicate fields.
+
+ @SYMTestActions
+ 1) Empty database.
+ 2) Import a vcard containing 2 Home Tel fields with EDefault flag.
+ 3) Check of all fields are imported
+ 4) Import the same vcard with 4 modified Home Tel fields and using CContactVCardConverter::EReplaceIfExists option
+
+ @SYMTestExpectedResults The vcard is replaced with the contact in the database when
+ the CContactVCardConverter::EReplaceIfExists flag is used.
+ */
+ void ImportDuplicateFieldVCardWithReplaceIfExitstL()
+ {
+
+ test.Next(_L("@SYMTestCaseID:PIM-T-CNTVCARD-INC110795-0001 checking Replacing existing contact with new one (has duplicate fields) using EReplaceIfExists"));
+
+ const TInt importOption1 = CContactDatabase::EDefault;
+ const TInt importOption2 = CContactDatabase::EDefault|
+ CContactDatabase::EImportSingleContact|
+ CContactDatabase::ENullTemplateId |
+ CContactVCardConverter::EReplaceIfExists;
+
+
+ CContactDatabase *db=CntTest->CreateDatabaseL();
+
+ // 1) Empty database.
+ EmptyDatabase();
+ TInt count = db->CountL();
+ test(count == 0);
+
+ // 2) Import a vcard containing 2 Home Tel fields with CContactDatabase::EDefault flag.
+ test.Next(_L("Importing Contact with 2 duplicate Home Tel fields"));
+ TContactItemId contactId;
+
+ RDesReadStream vcard(KVCardBeforeChange());
+ CleanupClosePushL(vcard);
+
+ CArrayPtr<CContactItem>* contactItems;
+ TBool success = EFalse;
+ contactItems = db->ImportContactsL(TUid::Uid(KUidVCardConvDefaultImpl), vcard, success, importOption1);
+ CleanupStack::PushL(TCleanupItem(CleanUpResetAndDestroy,contactItems));
+ contactId = (*contactItems)[0]->Id();
+ CleanupStack::PopAndDestroy(contactItems);
+ CleanupStack::PopAndDestroy(&vcard);
+
+ CContactItem *item = db->ReadContactLC(contactId);
+ CContactItemFieldSet& fieldSet = item->CardFields();
+
+ // Ensure all fields get imported
+ test(FindInFields(fieldSet, TPtrC16(KGivenName())));
+ test(FindInFields(fieldSet, TPtrC16(KFamilyName())));
+ test(FindInFields(fieldSet, TPtrC16(KTelHome1())));
+ test(FindInFields(fieldSet, TPtrC16(KTelHome2())));
+ test(FindInFields(fieldSet, TPtrC16(KTelCell())));
+
+ CleanupStack::PopAndDestroy(item);
+
+
+ //3) Import the same vcard with 4 modified Home tel fields and using
+ //CContactVCardConverter::EReplaceIfExists option
+ test.Next(_L("Importing Same Contact and replacing the old contact with 4 modified Home Tel field using EReplaceIfExists"));
+
+ RDesReadStream vcard2(KVCardAfterChange());
+ CleanupClosePushL(vcard2);
+
+ success = EFalse;
+ contactItems = db->ImportContactsL(TUid::Uid(KUidVCardConvDefaultImpl), vcard2, success, importOption2);
+ CleanupStack::PushL(TCleanupItem(CleanUpResetAndDestroy,contactItems));
+ contactId = (*contactItems)[0]->Id();
+ CleanupStack::PopAndDestroy(contactItems);
+ CleanupStack::PopAndDestroy(&vcard2);
+
+ item = db->ReadContactLC(contactId);
+
+ CContactItemFieldSet& fieldSet2 = item->CardFields();
+
+ //4) Ensure that the all 4 Home TEL field have been modified
+ test(FindInFields(fieldSet2, TPtrC16(KGivenName())));
+ test(FindInFields(fieldSet2, TPtrC16(KFamilyName())));
+ test(FindInFields(fieldSet2, TPtrC16(KTelHome1Modified())));
+ test(FindInFields(fieldSet2, TPtrC16(KTelHome2Modified())));
+ test(FindInFields(fieldSet2, TPtrC16(KTelHome3Modified())));
+ test(FindInFields(fieldSet2, TPtrC16(KTelHome4Modified())));
+
+ CleanupStack::PopAndDestroy(item);
+ }
+
+/**
+Utility function to check if a specific line is present in a file
+*/
+TBool CheckExportFilesL(const TDesC8& aString, const TDesC16& aFile)
+ {
+ RFile fileHandle;
+ TBool patternFound = EFalse;
+ fileHandle.Open(CntTest->Fs(), aFile, EFileRead|EFileStreamText);
+ CleanupClosePushL(fileHandle);
+ TBuf8<256> line;
+
+ while(fileHandle.Read(line) == KErrNone && line.Length() != 0)
+ {
+ if (line.Find(aString) != KErrNotFound)
+ {
+ patternFound = ETrue;
+ break;
+ }
+ }
+
+ CleanupStack::PopAndDestroy(&fileHandle);
+ return patternFound;
+ }
+
+/**
+@SYMTestCaseID PIM-T-CNTVCARD-INC102410-0001
+@SYMTestType UT
+@SYMTestPriority Critical
+@SYMTestCaseDesc Properties having multiple parameters should be imported properly.
+
+@SYMTestActions
+1.Import vCard having property with multiple parameter.
+2.Open imported contact and check if parameter values have been added as fields.
+3.Export imported contact and check if the property has been exported properly.
+
+@SYMTestExpectedResults For the above tests:
+1.vCard should be imported without losing data.
+2.Necessary parameters should be added as fields in contact.
+3.Exported file should contain all the parameters which were there while importing.
+4.No leaves or panics should occur
+*/
+void TestMultipleParamsInVCardPropertyL()
+ {
+ test.Next(_L("@SYMTestCaseID:PIM-T-CNTVCARD-INC102410-0001 Test Import of property having multiple parameters"));
+ CntTest->CreateDatabaseL();
+ TContactItemId contactId;
+
+ RDesReadStream vcard(KMultiParam());
+ CleanupClosePushL(vcard);
+
+ CArrayPtr<CContactItem>* contactItems;
+ TBool success = EFalse;
+ contactItems = CntTest->Db()->ImportContactsL(TUid::Uid(KUidVCardConvDefaultImpl), vcard, success, CContactDatabase::ETTFormat);
+ CleanupStack::PushL(TCleanupItem(CleanUpResetAndDestroy,contactItems));
+ contactId = (*contactItems)[0]->Id();
+ CleanupStack::PopAndDestroy(contactItems);
+ CleanupStack::PopAndDestroy(&vcard);
+
+ CContactItem* item = CntTest->Db()->ReadContactLC(contactId);
+
+ CContactItemFieldSet& fields = item->CardFields();
+ TInt fieldPos = fields.FindNext(KUidContactFieldVCardMapTEL, KContactFieldSetSearchAll);
+ const CContentType& content = fields[fieldPos].ContentType();
+
+ TBool result = 0;
+ result = content.ContainsFieldType(KUidContactFieldVCardMapCELL);
+ TEST_CONDITION(result > 0);
+
+ result = content.ContainsFieldType(KUidContactFieldVCardMapVOICE);
+ TEST_CONDITION(result > 0);
+
+ result = content.ContainsFieldType(KUidContactFieldVCardMapHOME);
+ TEST_CONDITION(result > 0);
+
+ CleanupStack::PopAndDestroy(item); //destroying contact item
+
+ CContactIdArray* idArray = CContactIdArray::NewL();
+ CleanupStack::PushL(idArray);
+ idArray->AddL(contactId);
+
+ RFileWriteStream fileStream;
+ User::LeaveIfError(fileStream.Replace(CntTest->Fs(), KOutputFileName, EFileWrite));
+ CleanupClosePushL(fileStream);
+
+ CntTest->Db()->ExportSelectedContactsL(TUid::Uid(KUidVCardConvDefaultImpl), *idArray, fileStream,0);
+ fileStream.CommitL();
+ CleanupStack::PopAndDestroy(&fileStream);
+
+ result = CheckExportFilesL(KTelExport(), KOutputFileName());
+ TEST_CONDITION(result > 0);
+
+
+ CleanupStack::PopAndDestroy(); //destroying id array
+ }
+
+/**
+@SYMTestCaseID PIM-T-CNTVCARD-PDEF103252-0001
+@SYMTestType UT
+@SYMTestPriority High
+@SYMTestCaseDesc Contact item having a large binary field should be exported properly without any leaves.
+
+@SYMTestActions
+1.Import vCard having PHOTO propery with very large property value.
+2.Export the imported contacts.
+3.Import the exported contacts.
+4.Compare the value of the PICTURE field present in the contact items resultin from two Import actions performed.
+
+@SYMTestExpectedResults For the above tests:
+1.vCard should be Exported without losing data or causing any low memory leaves.
+2.The Imported PHOTO data should be same in both cases.
+.No leaves or panics should occur
+*/
+void TestExportofContactHavingLargeBinaryFieldL()
+ {
+ test.Next(_L("@SYMTestCaseID:PIM-T-CNTVCARD-PDEF103252-0001 Test Export of contact having large binary field"));
+
+ // Empty the Database
+ CntTest->CreateDatabaseL();
+ CContactIdArray* idarray = CContactIdArray::NewL();
+ CleanupStack::PushL(idarray);
+ RFs fsSession;
+ User::LeaveIfError(fsSession.Connect());
+ RFileReadStream readStream;
+
+ //Import vcard with large PHOTO property
+ test.Printf(_L("Importing contacts from VCard"));
+ User::LeaveIfError(readStream.Open(fsSession, KVCardLargePhoto, EFileRead));
+ CleanupClosePushL(readStream);
+ TBool success = EFalse;
+ CArrayPtr<CContactItem>* contactItems = CntTest->Db()->ImportContactsL(TUid::Uid(KUidVCardConvDefaultImpl),
+ readStream, success, CContactDatabase::ETTFormat);
+
+ CleanupStack::PushL( TCleanupItem( CleanUpResetAndDestroy, contactItems ) );
+
+ TEST_CONDITION(contactItems->Count() == 1) ;
+
+ //adding imported contact Id's to idarray for export
+ idarray->AddL((*contactItems)[0]->Id());
+
+ CleanupStack::PopAndDestroy(contactItems);
+ CleanupStack::PopAndDestroy(&readStream);
+
+ test.Printf(_L("Exporting the Imported contacts, Testing it for both vCard2.1 and vCard3.0 export."));
+ RFileWriteStream writeStream;
+ TUid uid;
+
+ //vCard3.0
+ User::LeaveIfError(writeStream.Replace(fsSession,KVCardFile2, EFileWrite));
+ CleanupClosePushL(writeStream);
+ uid.iUid = KUidPBAPVCardConvImpl;
+ TInt64 filter = 0;
+ filter |= 0x08;
+ //This call should not leave with a Low memory Error
+ CntTest->Db()->ExportSelectedContactsL(uid, *idarray, writeStream, CContactDatabase::EDefault, filter, NULL, EPBAPVCard30,ETrue);
+ writeStream.CommitL();
+ CleanupStack::PopAndDestroy(&writeStream);
+
+ //vCard2.1
+ User::LeaveIfError(writeStream.Replace(fsSession, KVCardFile3, EFileWrite));
+ CleanupClosePushL(writeStream);
+ uid.iUid = KUidVCardConvDefaultImpl;
+ //This call should not leave with a Low memory Error
+ CntTest->Db()->ExportSelectedContactsL(uid, *idarray, writeStream, CContactDatabase::EDefault);
+ writeStream.CommitL();
+ CleanupStack::PopAndDestroy(&writeStream);
+ CleanupStack::PopAndDestroy(idarray);
+
+ test.Printf(_L("Export of large binary property completed successfully"));
+
+}
+
+/**
+@SYMTestCaseID PIM-T-CNTVCARD-PDEF140328-0001
+@SYMTestType UT
+@SYMTestPriority High
+@SYMTestCaseDesc Partial vCard's should be processed without any panics
+
+@SYMTestActions
+1.Import a partial vCard.
+
+@SYMTestExpectedResults For the above tests:
+1.There should be no panics while import is happening.
+*/
+ void TestImportingPartialOrEmptyVCardsL()
+{
+ test.Next(_L("Test import of partial vCard"));
+ CArrayPtr<CContactItem>* contactItems = NULL;
+ RDesReadStream vcard(KPartialVCard());
+ CleanupClosePushL(vcard);
+ TInt success = EFalse;
+ CContactDatabase* db = CntTest->CreateDatabaseL();
+ contactItems = db->ImportContactsL(TUid::Uid(KUidVCardConvDefaultImpl), vcard, success, CContactDatabase::EImportSingleContact);
+ CleanupStack::PushL( TCleanupItem( CleanUpResetAndDestroy, contactItems ) );
+ CleanupStack::PopAndDestroy(contactItems);
+ CleanupStack::PopAndDestroy(&vcard);
+ test.Printf(_L("Import of partial vCard completed successfully"));
+}
+
+
+/**
+
+@SYMTestCaseID PIM-T-CNTVCARD-0001
+
+*/
+
+LOCAL_C void DoTestsL()
+ {
+ test.Start(_L("@SYMTestCaseID:PIM-T-CNTVCARD-0001 Preparing tests"));
+ CTestRegister* TempFiles = CTestRegister::NewLC();
+ TempFiles->RegisterL(KVCardFile1);
+ TempFiles->RegisterL(KVCardFile2);
+ TempFiles->RegisterL(KVCardFile3);
+ TempFiles->RegisterL(KVCardUpdate2);
+ TempFiles->RegisterL(KDatabaseFileName, EFileTypeCnt);
+ TempFiles->RegisterL(KOutputFileName);
+ TempFiles->RegisterL(KExpDelAFileName);
+ TempFiles->RegisterL(KImpTypeVcardName);
+ TempFiles->RegisterL(KImpNoTypeVcardName);
+ TempFiles->RegisterL(KVCardFile5);
+ TempFiles->RegisterL(KVCardFile6);
+
+ //without the fix this test will cause User 21 panic in versit
+ TestImportingPartialOrEmptyVCardsL();
+ VCardEmailTestL();
+ AccessCountTestsL();
+ DefaultVoiceParamTestsL();
+ ExportContactTestL();
+ ExportNamelessContactTestL();
+#if defined(_DEBUG)
+ //this test cannot be run in release mode due to UID mismatch
+ //UpdateVCardTestL();
+#endif
+
+ ImportLargeVCardTestL() ;
+
+ DoTrailingSpaceImportAndExportTestL() ;
+ VCardLineFeedOnlyTestL();
+ VCardIgnoreUidTestL();
+ CheckTypeSupport(KImpTypeVcardName);
+ CheckTypeSupport(KImpNoTypeVcardName);
+ TestImportContactsL(KVCardFile5, KVCardFile6, KMasterVcard, KModifierVcard);
+ // ImportExportVCardWithBinaryKeyL called with binary KEY value
+ ImportExportVCardWithKeyL(KVCardBinaryKeyImportFileDes, KStorageTypeStore);
+ // ImportExportVCardWithBinaryKeyL called with text KEY value
+ ImportExportVCardWithKeyL(KVCardTextKeyImportFileDes, KStorageTypeText);
+ ImportVCardWithFlagReplaceIfExitstL();
+ ImportDuplicateFieldVCardWithReplaceIfExitstL();
+
+ TestMultipleParamsInVCardPropertyL();
+ TestExportofContactHavingLargeBinaryFieldL();
+
+ CntTest->CloseDatabase();
+ CleanupStack::PopAndDestroy(TempFiles);
+ }
+
+
+LOCAL_C void CleanupFilesL()
+ {
+ // delete the database file
+ if (CContactDatabase::ContactDatabaseExistsL(KDatabaseFileName) )
+ {
+ CContactDatabase::DeleteDatabaseL(KDatabaseFileName);
+ }
+ }
+
+
+LOCAL_C void TestCondition(TBool aCondition, TInt aLineNumber)
+ {
+ // if the test is about to fail, cleanup files first
+ if (!aCondition)
+ {
+ TRAP_IGNORE(CleanupFilesL());
+ }
+ test.operator()(aCondition, aLineNumber);
+ }
+
+
+GLDEF_C TInt E32Main()
+ {
+ __UHEAP_MARK;
+ CntTest=new(ELeave) CCntTest();
+ CntTest->ConstructL(test,KDatabaseFileName);
+ TRAPD(err,DoTestsL());
+ // ensure files are cleaned up even if DoTestsL() leaves
+ TRAP_IGNORE(CleanupFilesL() );
+ CntTest->EndTestLib(err);
+ __UHEAP_MARKEND;
+ return KErrNone;
+ }