--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/T_GENERALADDRESS.CPP Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,960 @@
+// 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:
+//
+
+// System includes
+#include <e32test.h>
+#include <f32file.h>
+#include <s32file.h>
+#include <cntdb.h>
+#include <cntdef.h>
+#include <cntitem.h>
+#include <cntfield.h>
+#include <cntfldst.h>
+#include <bautils.h>
+#include <barsc.h>
+#include <barsread.h>
+#include <versit.h>
+#include <vcard.h>
+#include <e32def.h>
+#include <coreappstest/testserver.h>
+// User includes
+#include "T_UTILS.H"
+
+// Flags
+#define OOM_TESTS
+
+// Globals
+static RTest TheTest(_L("T_GENERALADDRESS - Test General Address Export and Import"));
+static CCntTest* TheTestHelper;
+
+// Type definitions
+typedef void (*TGAFunction)(TBool& aPrintedTestTitle);
+
+// Constants
+const TInt KIntContactFieldVCardMapGENERALADDRESS = 0;
+const TUid KUidContactFieldVCardMapGENERALADDRESS = { KIntContactFieldVCardMapGENERALADDRESS };
+
+// Literal constants
+_LIT(KTestDatabaseFile, "C:GeneralAddressDatabase.cdb");
+//
+_LIT(KTestNameFamily, "Bloggs");
+_LIT(KTestNameGiven, "Joe");
+//
+_LIT(KTestAddressHOME, "_HOME");
+_LIT(KTestAddressWORK, "_WORK");
+_LIT(KTestAddressPREF, "_PREF");
+_LIT(KTestAddressGENERALADDRESS, "_GENERALADDRESS");
+//
+_LIT(KTestAddressPOSTOFFICE, "POSTOFFICE");
+_LIT(KTestAddressEXTENDEDADR, "EXTENDEDADR");
+_LIT(KTestAddressADR, "ADR");
+_LIT(KTestAddressLOCALITY, "LOCALITY");
+_LIT(KTestAddressREGION, "REGION");
+_LIT(KTestAddressPOSTCODE, "POSTCODE");
+_LIT(KTestAddressCOUNTRY, "COUNTRY");
+//
+_LIT(KTestVCardExportFileName, "C:\\T_GENERALADDRESS_EXPORTED.TXT");
+_LIT(KTestVCardImportFileName, "C:\\T_GENERALADDRESS_IMPORTED.TXT");
+//
+_LIT8(KVersitParam8GeneralAddress, "");
+
+
+// Utility methods
+
+/**
+ * Create a simple contact with just the name fields populated
+ */
+static TContactItemId CreateContactL(CContactDatabase& aDatabase)
+ {
+ const TContactItemId templateId = aDatabase.TemplateId();
+ //
+ CContactItem* templateCard = aDatabase.ReadContactLC(templateId);
+ CContactCard* card = CContactCard::NewL(templateCard);
+ CleanupStack::PushL(card);
+ //
+ SetNameL(*card, KUidContactFieldFamilyName, KUidContactFieldVCardMapUnusedN, KTestNameFamily, EFalse);
+ SetNameL(*card, KUidContactFieldGivenName, KUidContactFieldVCardMapUnusedN, KTestNameGiven, EFalse);
+ //
+ const TContactItemId id = aDatabase.AddNewContactL(*card);
+ CleanupStack::PopAndDestroy(2, templateCard);
+ return id;
+ }
+
+/**
+ * Combine a value and a postfix to create a real unified value
+ */
+static HBufC* ConstructAddressValueLC(const TDesC& aValue, const TDesC& aPostFix)
+ {
+ HBufC* value = HBufC::NewLC(aValue.Length() + aPostFix.Length());
+ TPtr pValue(value->Des());
+ pValue = aValue;
+ pValue.Append(aPostFix);
+ //
+ return value;
+ }
+
+/**
+ * Add a specific address field to a vCard
+ */
+static void AddAddressFieldL(CContactItem& aContact, TFieldType aFieldType, TUid aMapping, TFieldType aExtraFieldType, const TDesC& aValue, const TDesC& aValuePostFix)
+ {
+ CContentType* content = CContentType::NewL(aFieldType, aMapping);
+ CleanupStack::PushL(content);
+ content->AddFieldTypeL(aExtraFieldType);
+ //
+ CContactItemField* contactItemField = CContactItemField::NewLC(KStorageTypeText, *content);
+ //
+ HBufC* value = ConstructAddressValueLC(aValue, aValuePostFix);
+ //
+ contactItemField->TextStorage()->SetStandardTextL(*value);
+ CleanupStack::PopAndDestroy(value);
+ //
+ aContact.AddFieldL(*contactItemField);
+ CleanupStack::Pop(contactItemField);
+ //
+ CleanupStack::PopAndDestroy(content);
+ }
+
+/**
+ * Return the post fix descriptor for a given field type (HOME, WORK, PREF, General)
+ */
+static TPtrC PostFixForFieldType(TFieldType aType)
+ {
+ TPtrC postFix(KNullDesC);
+ switch(aType.iUid)
+ {
+ case KIntContactFieldVCardMapHOME:
+ postFix.Set(KTestAddressHOME);
+ break;
+ case KIntContactFieldVCardMapWORK:
+ postFix.Set(KTestAddressWORK);
+ break;
+ case KIntContactFieldVCardMapPREF:
+ postFix.Set(KTestAddressPREF);
+ break;
+ case KIntContactFieldVCardMapGENERALADDRESS:
+ postFix.Set(KTestAddressGENERALADDRESS);
+ break;
+ default:
+ TheTest(EFalse);
+ break;
+ }
+ //
+ return postFix;
+ }
+
+/**
+ * Add a specific address type to a contact card
+ */
+static void AddAddressL(CContactDatabase& aDatabase, TContactItemId aId, TFieldType aExtraFieldType)
+ {
+ const TPtrC postFix(PostFixForFieldType(aExtraFieldType));
+ //
+ CContactItem* card = aDatabase.OpenContactLX(aId);
+ CleanupStack::PushL(card);
+ //
+ AddAddressFieldL(*card, KUidContactFieldPostOffice, KUidContactFieldVCardMapPOSTOFFICE, aExtraFieldType, KTestAddressPOSTOFFICE, postFix);
+ AddAddressFieldL(*card, KUidContactFieldExtendedAddress, KUidContactFieldVCardMapEXTENDEDADR, aExtraFieldType, KTestAddressEXTENDEDADR, postFix);
+ AddAddressFieldL(*card, KUidContactFieldAddress, KUidContactFieldVCardMapADR, aExtraFieldType, KTestAddressADR, postFix);
+ AddAddressFieldL(*card, KUidContactFieldLocality, KUidContactFieldVCardMapLOCALITY, aExtraFieldType, KTestAddressLOCALITY, postFix);
+ AddAddressFieldL(*card, KUidContactFieldRegion, KUidContactFieldVCardMapREGION, aExtraFieldType, KTestAddressREGION, postFix);
+ AddAddressFieldL(*card, KUidContactFieldPostcode, KUidContactFieldVCardMapPOSTCODE, aExtraFieldType, KTestAddressPOSTCODE, postFix);
+ AddAddressFieldL(*card, KUidContactFieldCountry, KUidContactFieldVCardMapCOUNTRY, aExtraFieldType, KTestAddressCOUNTRY, postFix);
+ //
+ aDatabase.CommitContactL(*card);
+ CleanupStack::PopAndDestroy(card);
+ CleanupStack::Pop(); // lock record
+ }
+
+/**
+ * Export a specific contact to a vCard file
+ */
+static void ExportContactAsVCardL(CContactDatabase& aDatabase, TContactItemId aId, RFs& aFsSession, const TDesC& aVCardFileName)
+ {
+ CContactIdArray* idArray = CContactIdArray::NewLC();
+ idArray->AddL(aId);
+ //
+ RFile outfile;
+ const TInt error = outfile.Replace(aFsSession, aVCardFileName, EFileWrite);
+ User::LeaveIfError(error);
+ CleanupClosePushL(outfile);
+ //
+ RFileWriteStream writeStream(outfile);
+ CleanupClosePushL(writeStream);
+ //
+ const TUid KVersitVCardUid = { KUidVCardConvDefaultImpl };
+ aDatabase.ExportSelectedContactsL(KVersitVCardUid, *idArray, writeStream, CContactDatabase::EDefault);
+ writeStream.CommitL();
+ CleanupStack::PopAndDestroy(3, idArray); // writeStream, outfile, idArray
+ }
+
+/**
+ * Parse a file using the Symbian vCard parser and return the parsed data structures
+ * to the caller
+ */
+static CParserVCard* ParseVCardFileLC(RFs& aFsSession, const TDesC& aVCardFileName)
+ {
+ CParserVCard* parser = CParserVCard::NewL();
+ CleanupStack::PushL(parser);
+ //
+ RFile readFile;
+ const TInt error = readFile.Open(aFsSession, aVCardFileName, EFileRead);
+ User::LeaveIfError(error);
+ CleanupClosePushL(readFile);
+ //
+ RFileReadStream readStream(readFile);
+ CleanupClosePushL(readStream);
+ parser->InternalizeL(readStream);
+ CleanupStack::PopAndDestroy(2); // readStream, readFile
+ //
+ return parser;
+ }
+
+/**
+ * Returns the property parameter name value used by Versit for this particular
+ * Contacts Model field type (E.g. HOME, WORK, PREF, etc). Returns KNullDesC in
+ * the case of General Address. Panic (fails the test) if the type is not recognised.
+ */
+static TPtrC8 VersitPropertyParameterNameForContactsModelFieldType(TFieldType aAddressType)
+ {
+ TPtrC8 propParamValue(KNullDesC8);
+ //
+ switch(aAddressType.iUid)
+ {
+ case KIntContactFieldVCardMapHOME:
+ propParamValue.Set(KVersitParam8Home);
+ break;
+ case KIntContactFieldVCardMapWORK:
+ propParamValue.Set(KVersitParam8Work);
+ break;
+ case KIntContactFieldVCardMapPREF:
+ propParamValue.Set(KVersitParam8Pref);
+ break;
+ case KIntContactFieldVCardMapGENERALADDRESS:
+ break;
+ default:
+ TheTest(EFalse);
+ break;
+ }
+ //
+ return propParamValue;
+ }
+
+/**
+ * Search a vCard property for the presence of a specific address type, e.g. HOME, WORK, PREF or "General"
+ */
+static TBool ValidateVCardPropertyForAddressType(const CParserProperty& aProperty, const TDesC8& aPropertyParameterType)
+ {
+ TBool validated = EFalse;
+
+ // Have to perform more substancial checks if we're looking for just a general address...
+ if (aPropertyParameterType.Length())
+ {
+ // HOME, WORK, PREF
+ validated = (aProperty.Param(aPropertyParameterType) != NULL);
+ }
+ else
+ {
+ // In the case of General Address, which won't have an associated property parameter
+ // we must check that none of the other types are present for this address. If none are
+ // matched, then this address can be considered general.
+ const TBool foundHOME = (aProperty.Param(KVersitParam8Home) != NULL);
+ const TBool foundWORK = (aProperty.Param(KVersitParam8Work) != NULL);
+ const TBool foundPREF = (aProperty.Param(KVersitParam8Pref) != NULL);
+ //
+ validated = !(foundHOME || foundWORK || foundPREF);
+ }
+ //
+ return validated;
+ }
+
+/**
+ * Check that the specified actual value found in the vCard matches the expected value
+ * which is constructed from the raw value and post fix.
+ */
+static TBool ValidateAddressSubFieldL(const TDesC& aActualValue, const TDesC& aExpectedRawValue, const TDesC& aPostFix)
+ {
+ HBufC* expectedValue = ConstructAddressValueLC(aExpectedRawValue, aPostFix);
+ const TBool match = (expectedValue->CompareF(aActualValue) == 0);
+ CleanupStack::PopAndDestroy(expectedValue);
+ //
+ return match;
+ }
+
+/**
+ * Check that the specified array contains exact matches for each of the 7 address
+ * sub field values.
+ */
+static TBool ValidateAddressSubFieldValuesL(const CDesCArray& aArray, const TDesC& aPostFix)
+ {
+ TPtrC actualValue;
+ //
+ actualValue.Set(aArray[0]);
+ if (!ValidateAddressSubFieldL(actualValue, KTestAddressPOSTOFFICE, aPostFix))
+ return EFalse;
+ actualValue.Set(aArray[1]);
+ if (!ValidateAddressSubFieldL(actualValue, KTestAddressEXTENDEDADR, aPostFix))
+ return EFalse;
+ actualValue.Set(aArray[2]);
+ if (!ValidateAddressSubFieldL(actualValue, KTestAddressADR, aPostFix))
+ return EFalse;
+ actualValue.Set(aArray[3]);
+ if (!ValidateAddressSubFieldL(actualValue, KTestAddressLOCALITY, aPostFix))
+ return EFalse;
+ actualValue.Set(aArray[4]);
+ if (!ValidateAddressSubFieldL(actualValue, KTestAddressREGION, aPostFix))
+ return EFalse;
+ actualValue.Set(aArray[5]);
+ if (!ValidateAddressSubFieldL(actualValue, KTestAddressPOSTCODE, aPostFix))
+ return EFalse;
+ actualValue.Set(aArray[6]);
+ if (!ValidateAddressSubFieldL(actualValue, KTestAddressCOUNTRY, aPostFix))
+ return EFalse;
+ //
+ return ETrue;
+ }
+
+/**
+ * Check a vCard for the presence of a specific address type. Returns ETrue
+ * if the type is found within the vCard.
+ */
+static TBool ValidateVCardForAddressL(CParserVCard& aVCard, TFieldType aAddressType)
+ {
+ TBool validated = EFalse;
+ const TUid KVersitAddressPropertyValueType = { KVersitPropertyCDesCArrayUid };
+ const TPtrC8 propValueType = VersitPropertyParameterNameForContactsModelFieldType(aAddressType);
+ //
+ CArrayPtr<CParserProperty>* properties = aVCard.PropertyL(KVersitTokenADR, KVersitAddressPropertyValueType, EFalse);
+ if (properties)
+ {
+ CleanupStack::PushL(properties);
+ const TInt count = properties->Count();
+ for(TInt i=0; i<count || !validated; i++)
+ {
+ // First verify the property parameters
+ CParserProperty& property = *properties->At(i);
+ if (ValidateVCardPropertyForAddressType(property, propValueType))
+ {
+ // Next verify the property values
+ CParserPropertyValueCDesCArray* value = static_cast<CParserPropertyValueCDesCArray*>(property.Value());
+ CDesCArray* array = value->Value();
+
+ // There must be 7 sub-fields
+ if (array->MdcaCount() == 7)
+ {
+ // Check each sub-field for the correct value
+ const TPtrC postFix = PostFixForFieldType(aAddressType);
+ validated = ValidateAddressSubFieldValuesL(*array, postFix);
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy(properties);
+ }
+ return validated;
+ }
+
+/**
+ * Create a vCard N property and add it to the specified vCard parser object
+ */
+static void AddNameToVCardL(CParserVCard& aVCard)
+ {
+ // For the property value itself
+ CDesCArrayFlat* desArray = new (ELeave)CDesCArrayFlat(4);
+ CleanupStack::PushL(desArray);
+
+ // Add the names
+ desArray->AppendL(KTestNameFamily);
+ desArray->AppendL(KTestNameGiven);
+ desArray->AppendL(KNullDesC);
+ desArray->AppendL(KNullDesC);
+ desArray->AppendL(KNullDesC);
+
+ // Create the property value
+ CParserPropertyValue* value = new(ELeave) CParserPropertyValueCDesCArray(desArray);
+ CleanupStack::Pop(desArray);
+ CleanupStack::PushL(value);
+ //
+ CParserGroupedProperty* property = CParserGroupedProperty::NewL(*value, KVersitTokenN, NULL, NULL);
+ CleanupStack::Pop(value); // value
+
+ // This pushes property before anything can leave...
+ aVCard.AddPropertyL(property);
+ }
+
+/**
+ * Combine the address data and the post fix to form a new combined address data value
+ * and append it to the specified array
+ */
+static void AddAddressSubFieldToArrayL(CDesCArray& aArray, const TDesC& aAddress, const TDesC& aPostFix)
+ {
+ HBufC* value = ConstructAddressValueLC(aAddress, aPostFix);
+ aArray.AppendL(*value);
+ CleanupStack::PopAndDestroy(value);
+ }
+
+/**
+ * Create a vCard ADR property and add it to the specified vCard parser object
+ */
+static void AddAddressToVCardL(CParserVCard& aVCard, const TDesC8& aAddressType)
+ {
+ // For the property parameters
+ CArrayPtr<CParserParam>* arrayOfParams = new(ELeave) CArrayPtrFlat<CParserParam>(5);
+ CleanupStack::PushL(TCleanupItem(CleanUpResetAndDestroy, arrayOfParams));
+
+ // If the address type is NULL then its a general address, in which case it doesn't
+ // need a property parameter. Otherwise, assume it does
+ if (aAddressType.Length())
+ {
+ CParserParam* parserParam = CParserParam::NewL(aAddressType, KNullDesC);
+ CleanupStack::PushL(parserParam);
+ arrayOfParams->AppendL(parserParam);
+ CleanupStack::Pop(parserParam);
+ }
+
+ // Create the value array
+ CDesCArrayFlat* desArray = new (ELeave)CDesCArrayFlat(4);
+ CleanupStack::PushL(desArray);
+
+ // Pick the correct postfix
+ TPtrC postFix(KNullDesC);
+ if (aAddressType == KVersitParam8Home)
+ postFix.Set(KTestAddressHOME);
+ else if (aAddressType == KVersitParam8Work)
+ postFix.Set(KTestAddressWORK);
+ else if (aAddressType == KVersitParam8Pref)
+ postFix.Set(KTestAddressPREF);
+ else if (aAddressType == KVersitParam8GeneralAddress)
+ postFix.Set(KTestAddressGENERALADDRESS);
+
+ // Add the names
+ AddAddressSubFieldToArrayL(*desArray, KTestAddressPOSTOFFICE, postFix);
+ AddAddressSubFieldToArrayL(*desArray, KTestAddressEXTENDEDADR, postFix);
+ AddAddressSubFieldToArrayL(*desArray, KTestAddressADR, postFix);
+ AddAddressSubFieldToArrayL(*desArray, KTestAddressLOCALITY, postFix);
+ AddAddressSubFieldToArrayL(*desArray, KTestAddressREGION, postFix);
+ AddAddressSubFieldToArrayL(*desArray, KTestAddressPOSTCODE, postFix);
+ AddAddressSubFieldToArrayL(*desArray, KTestAddressCOUNTRY, postFix);
+
+ // Create the property value
+ CParserPropertyValue* value = new (ELeave) CParserPropertyValueCDesCArray(desArray);
+ CleanupStack::Pop(desArray);
+ CleanupStack::PushL(value);
+
+ // And finally, the property itself
+ CParserGroupedProperty* property = CParserGroupedProperty::NewL(*value, KVersitTokenADR, NULL, arrayOfParams);
+ CleanupStack::Pop(2, arrayOfParams); // value, arrayOfParams
+
+ // Add to vCard object - takes ownership of property immediately
+ aVCard.AddPropertyL(property);
+ }
+
+/**
+ * Create a simple vCard which contains only an N (Name) property
+ */
+static CParserVCard* CreateVCardLC()
+ {
+ CParserVCard* parser = CParserVCard::NewL();
+ CleanupStack::PushL(parser);
+ //
+ AddNameToVCardL(*parser);
+ //
+ return parser;
+ }
+
+/**
+ * Export the specified vCard object to a file
+ */
+static void CreateVCardFileFromVCardObjectL(CParserVCard& aVCard, RFs& aFsSession, const TDesC& aVCardFileName)
+ {
+ RFile outfile;
+ const TInt error = outfile.Replace(aFsSession, aVCardFileName, EFileWrite);
+ User::LeaveIfError(error);
+ CleanupClosePushL(outfile);
+ //
+ RFileWriteStream writeStream(outfile);
+ CleanupClosePushL(writeStream);
+ //
+ aVCard.ExternalizeL(writeStream);
+ writeStream.CommitL();
+ CleanupStack::PopAndDestroy(2); // writeStream, outfile
+ }
+
+/**
+ * Import the specified vCard to the contacts database and return the newly created contact item
+ */
+static CContactItem* ImportVCardLC(CContactDatabase& aDatabase, RFs& aFsSession, const TDesC& aVCardFileName)
+ {
+ RFile readFile;
+ const TInt error = readFile.Open(aFsSession, aVCardFileName, EFileRead);
+ User::LeaveIfError(error);
+ CleanupClosePushL(readFile);
+ //
+ RFileReadStream readStream(readFile);
+ CleanupClosePushL(readStream);
+ //
+ TBool importSuccessful = EFalse;
+ const TInt options = CContactDatabase::EDefault;
+ const TUid KVersitVCardUid = { KUidVCardConvDefaultImpl };
+ //
+ CArrayPtr<CContactItem>* contacts = aDatabase.ImportContactsL(KVersitVCardUid, readStream, importSuccessful, options);
+ CleanupStack::PopAndDestroy(2); // readStream, readFile
+
+ // Check import results
+ TheTest(importSuccessful);
+ TheTest(contacts != NULL);
+ TheTest(contacts->Count() == 1);
+
+ // Delete container, but not the contact itself
+ CContactItem* item = contacts->At(0);
+ CleanupStack::PushL(item);
+ delete contacts;
+ return item;
+ }
+
+/**
+ * Check the specified field set for the presence of a specific field which conforms
+ * to the specified address type
+ */
+static TBool LocateAddressFieldByType(CContactItemFieldSet& aFieldSet, TFieldType aFieldType, TUid aMapping, const TDesC& aExpectedValue, const TDesC& aExpectedPostFix)
+ {
+ TBool located = EFalse;
+
+ // Locate field
+ TInt pos = KErrNotFound;
+ if (aFieldType != KNullUid) // KNullUid is for general address
+ pos = aFieldSet.Find(aFieldType, aMapping);
+ else
+ pos = aFieldSet.Find(aMapping);
+ //
+ if (pos != KErrNotFound)
+ {
+ // Make real value
+ HBufC* value = ConstructAddressValueLC(aExpectedValue, aExpectedPostFix);
+
+ // Verify
+ CContactItemField& field = aFieldSet[pos];
+ CContactTextField* storage = field.TextStorage();
+ located = (storage->Text().CompareF(*value) == 0);
+ //
+ CleanupStack::PopAndDestroy(value);
+ }
+ //
+ return located;
+ }
+
+/**
+ * Check the specified contact card contains an address corresponding to the specified type
+ */
+static TBool ValidateContactForAddressTypeL(CContactItem& aContact, TFieldType aAddressType)
+ {
+ CContactItemFieldSet& fieldSet = aContact.CardFields();
+ const TPtrC postFix(PostFixForFieldType(aAddressType));
+ //
+ if (!LocateAddressFieldByType(fieldSet, aAddressType, KUidContactFieldVCardMapPOSTOFFICE, KTestAddressPOSTOFFICE, postFix))
+ return EFalse;
+ if (!LocateAddressFieldByType(fieldSet, aAddressType, KUidContactFieldVCardMapEXTENDEDADR, KTestAddressEXTENDEDADR, postFix))
+ return EFalse;
+ if (!LocateAddressFieldByType(fieldSet, aAddressType, KUidContactFieldVCardMapADR, KTestAddressADR, postFix))
+ return EFalse;
+ if (!LocateAddressFieldByType(fieldSet, aAddressType, KUidContactFieldVCardMapLOCALITY, KTestAddressLOCALITY, postFix))
+ return EFalse;
+ if (!LocateAddressFieldByType(fieldSet, aAddressType, KUidContactFieldVCardMapREGION, KTestAddressREGION, postFix))
+ return EFalse;
+ if (!LocateAddressFieldByType(fieldSet, aAddressType, KUidContactFieldVCardMapPOSTCODE, KTestAddressPOSTCODE, postFix))
+ return EFalse;
+ if (!LocateAddressFieldByType(fieldSet, aAddressType, KUidContactFieldVCardMapCOUNTRY, KTestAddressCOUNTRY, postFix))
+ return EFalse;
+ //
+ return ETrue;
+ }
+
+
+// Tests
+
+static void Test1L(TBool& aPrintedTestTitle)
+ {
+ if (!aPrintedTestTitle)
+ {
+ TheTest.Next(_L("EXPORT General address"));
+
+ aPrintedTestTitle = ETrue;
+ }
+ //
+ RFs& fsSession = TheTestHelper->Fs();
+ CContactDatabase& database = *TheTestHelper->Db();
+ //
+ const TContactItemId contactId = CreateContactL(database);
+ AddAddressL(database, contactId, KUidContactFieldVCardMapGENERALADDRESS);
+ ExportContactAsVCardL(database, contactId, fsSession, KTestVCardExportFileName);
+ CParserVCard* parser = ParseVCardFileLC(fsSession, KTestVCardExportFileName);
+ TheTest(ValidateVCardForAddressL(*parser, KUidContactFieldVCardMapGENERALADDRESS));
+ CleanupStack::PopAndDestroy(parser);
+ }
+
+static void Test2L(TBool& aPrintedTestTitle)
+ {
+ if (!aPrintedTestTitle)
+ {
+ TheTest.Next(_L("EXPORT General, Home address"));
+
+ aPrintedTestTitle = ETrue;
+ }
+ //
+ RFs& fsSession = TheTestHelper->Fs();
+ CContactDatabase& database = *TheTestHelper->Db();
+ //
+ const TContactItemId contactId = CreateContactL(database);
+ AddAddressL(database, contactId, KUidContactFieldVCardMapGENERALADDRESS);
+ AddAddressL(database, contactId, KUidContactFieldVCardMapHOME);
+ ExportContactAsVCardL(database, contactId, fsSession, KTestVCardExportFileName);
+ CParserVCard* parser = ParseVCardFileLC(fsSession, KTestVCardExportFileName);
+ TheTest(ValidateVCardForAddressL(*parser, KUidContactFieldVCardMapGENERALADDRESS));
+ TheTest(ValidateVCardForAddressL(*parser, KUidContactFieldVCardMapHOME));
+ CleanupStack::PopAndDestroy(parser);
+ }
+
+static void Test3L(TBool& aPrintedTestTitle)
+ {
+ if (!aPrintedTestTitle)
+ {
+ TheTest.Next(_L("EXPORT General, Work address"));
+
+ aPrintedTestTitle = ETrue;
+ }
+ //
+ RFs& fsSession = TheTestHelper->Fs();
+ CContactDatabase& database = *TheTestHelper->Db();
+ //
+ const TContactItemId contactId = CreateContactL(database);
+ AddAddressL(database, contactId, KUidContactFieldVCardMapGENERALADDRESS);
+ AddAddressL(database, contactId, KUidContactFieldVCardMapWORK);
+ ExportContactAsVCardL(database, contactId, fsSession, KTestVCardExportFileName);
+ CParserVCard* parser = ParseVCardFileLC(fsSession, KTestVCardExportFileName);
+ TheTest(ValidateVCardForAddressL(*parser, KUidContactFieldVCardMapGENERALADDRESS));
+ TheTest(ValidateVCardForAddressL(*parser, KUidContactFieldVCardMapWORK));
+ CleanupStack::PopAndDestroy(parser);
+ }
+
+
+static void Test4L(TBool& aPrintedTestTitle)
+ {
+ if (!aPrintedTestTitle)
+ {
+ TheTest.Next(_L("EXPORT General, Home, Work address"));
+
+ aPrintedTestTitle = ETrue;
+ }
+ //
+ RFs& fsSession = TheTestHelper->Fs();
+ CContactDatabase& database = *TheTestHelper->Db();
+ //
+ const TContactItemId contactId = CreateContactL(database);
+ AddAddressL(database, contactId, KUidContactFieldVCardMapGENERALADDRESS);
+ AddAddressL(database, contactId, KUidContactFieldVCardMapHOME);
+ AddAddressL(database, contactId, KUidContactFieldVCardMapWORK);
+ ExportContactAsVCardL(database, contactId, fsSession, KTestVCardExportFileName);
+ CParserVCard* parser = ParseVCardFileLC(fsSession, KTestVCardExportFileName);
+ TheTest(ValidateVCardForAddressL(*parser, KUidContactFieldVCardMapGENERALADDRESS));
+ TheTest(ValidateVCardForAddressL(*parser, KUidContactFieldVCardMapHOME));
+ TheTest(ValidateVCardForAddressL(*parser, KUidContactFieldVCardMapWORK));
+ CleanupStack::PopAndDestroy(parser);
+ }
+
+
+static void Test5L(TBool& aPrintedTestTitle)
+ {
+ if (!aPrintedTestTitle)
+ {
+ TheTest.Next(_L("IMPORT General address"));
+
+ aPrintedTestTitle = ETrue;
+ }
+ //
+ RFs& fsSession = TheTestHelper->Fs();
+ CContactDatabase& database = *TheTestHelper->Db();
+ //
+ CParserVCard* vCard = CreateVCardLC();
+ AddAddressToVCardL(*vCard, KVersitParam8GeneralAddress);
+ CreateVCardFileFromVCardObjectL(*vCard, fsSession, KTestVCardImportFileName);
+ CleanupStack::PopAndDestroy(vCard);
+ CContactItem* item = ImportVCardLC(database, fsSession, KTestVCardImportFileName);
+ TheTest(ValidateContactForAddressTypeL(*item, KUidContactFieldVCardMapGENERALADDRESS));
+ CleanupStack::PopAndDestroy(item);
+ }
+
+static void Test6L(TBool& aPrintedTestTitle)
+ {
+ if (!aPrintedTestTitle)
+ {
+ TheTest.Next(_L("IMPORT General, Home address"));
+
+ aPrintedTestTitle = ETrue;
+ }
+ //
+ RFs& fsSession = TheTestHelper->Fs();
+ CContactDatabase& database = *TheTestHelper->Db();
+ //
+ CParserVCard* vCard = CreateVCardLC();
+ AddAddressToVCardL(*vCard, KVersitParam8GeneralAddress);
+ AddAddressToVCardL(*vCard, KVersitParam8Home);
+ CreateVCardFileFromVCardObjectL(*vCard, fsSession, KTestVCardImportFileName);
+ CleanupStack::PopAndDestroy(vCard);
+ CContactItem* item = ImportVCardLC(database, fsSession, KTestVCardImportFileName);
+ TheTest(ValidateContactForAddressTypeL(*item, KUidContactFieldVCardMapGENERALADDRESS));
+ TheTest(ValidateContactForAddressTypeL(*item, KUidContactFieldVCardMapHOME));
+ CleanupStack::PopAndDestroy(item);
+ }
+
+
+static void Test7L(TBool& aPrintedTestTitle)
+ {
+ if (!aPrintedTestTitle)
+ {
+ TheTest.Next(_L("IMPORT General, Work address"));
+
+ aPrintedTestTitle = ETrue;
+ }
+ //
+ RFs& fsSession = TheTestHelper->Fs();
+ CContactDatabase& database = *TheTestHelper->Db();
+ //
+ CParserVCard* vCard = CreateVCardLC();
+ AddAddressToVCardL(*vCard, KVersitParam8GeneralAddress);
+ AddAddressToVCardL(*vCard, KVersitParam8Work);
+ CreateVCardFileFromVCardObjectL(*vCard, fsSession, KTestVCardImportFileName);
+ CleanupStack::PopAndDestroy(vCard);
+ CContactItem* item = ImportVCardLC(database, fsSession, KTestVCardImportFileName);
+ TheTest(ValidateContactForAddressTypeL(*item, KUidContactFieldVCardMapGENERALADDRESS));
+ TheTest(ValidateContactForAddressTypeL(*item, KUidContactFieldVCardMapWORK));
+ CleanupStack::PopAndDestroy(item);
+ }
+
+
+static void Test8L(TBool& aPrintedTestTitle)
+ {
+ if (!aPrintedTestTitle)
+ {
+ TheTest.Next(_L("IMPORT General, Home, Work address"));
+
+ aPrintedTestTitle = ETrue;
+ }
+ RFs& fsSession = TheTestHelper->Fs();
+ CContactDatabase& database = *TheTestHelper->Db();
+ //
+ CParserVCard* vCard = CreateVCardLC();
+ AddAddressToVCardL(*vCard, KVersitParam8GeneralAddress);
+ AddAddressToVCardL(*vCard, KVersitParam8Home);
+ AddAddressToVCardL(*vCard, KVersitParam8Work);
+ CreateVCardFileFromVCardObjectL(*vCard, fsSession, KTestVCardImportFileName);
+ CleanupStack::PopAndDestroy(vCard);
+ CContactItem* item = ImportVCardLC(database, fsSession, KTestVCardImportFileName);
+ TheTest(ValidateContactForAddressTypeL(*item, KUidContactFieldVCardMapGENERALADDRESS));
+ TheTest(ValidateContactForAddressTypeL(*item, KUidContactFieldVCardMapHOME));
+ TheTest(ValidateContactForAddressTypeL(*item, KUidContactFieldVCardMapWORK));
+ CleanupStack::PopAndDestroy(item);
+ }
+
+static void RunListOfTestsL(const RArray<TGAFunction>& aTests)
+ {
+ TBool printedTestTitle = EFalse;
+ const TInt count = aTests.Count();
+ for(TInt i=0; i<count; i++)
+ {
+ TGAFunction test = aTests[i];
+ TheTestHelper->CreateDatabaseL();
+ TRAPD(err, (*test)(printedTestTitle));
+
+ // Ensure that we close the database if a leave occurs or
+ // else the OOM test code thinks we've leaked it
+ TheTestHelper->CloseDatabase();
+
+ // Cascade error
+ User::LeaveIfError(err);
+
+ printedTestTitle = EFalse;
+ }
+ }
+
+static void TestExportL()
+ {
+ RArray<TGAFunction> array;
+ CleanupClosePushL(array);
+ //
+ User::LeaveIfError(array.Append(static_cast<TGAFunction>(Test1L)));
+ User::LeaveIfError(array.Append(static_cast<TGAFunction>(Test2L)));
+ User::LeaveIfError(array.Append(static_cast<TGAFunction>(Test3L)));
+ User::LeaveIfError(array.Append(static_cast<TGAFunction>(Test4L)));
+ //
+ RunListOfTestsL(array);
+ //
+ CleanupStack::PopAndDestroy(&array);
+ }
+
+static void TestImportL()
+ {
+ RArray<TGAFunction> array;
+ CleanupClosePushL(array);
+ //
+ User::LeaveIfError(array.Append(static_cast<TGAFunction>(Test5L)));
+ User::LeaveIfError(array.Append(static_cast<TGAFunction>(Test6L)));
+ User::LeaveIfError(array.Append(static_cast<TGAFunction>(Test7L)));
+ User::LeaveIfError(array.Append(static_cast<TGAFunction>(Test8L)));
+ //
+ RunListOfTestsL(array);
+ //
+ CleanupStack::PopAndDestroy(&array);
+ }
+
+
+static void RunTestsL()
+ {
+ TRAPD(errExport, TestExportL());
+ TheTest(errExport == KErrNone || errExport == KErrNoMemory);
+ //
+ TRAPD(errImport, TestImportL());
+ TheTest(errImport == KErrNone || errImport == KErrNoMemory);
+ }
+
+#ifdef OOM_TESTS
+
+static void ExpandCleanupStackL()
+ {
+ // Reserve some space on the cleanup stack:
+ {
+ for (TInt ii=0;ii<1000;++ii)
+ CleanupStack::PushL(&ii);
+ }
+ CleanupStack::Pop(1000);
+ }
+
+static void PrepareTestSkipsL(RArray<TInt>& aSkipArray, TInt aCount, ...)
+ {
+ aSkipArray.Reset();
+ //
+ VA_LIST list;
+ VA_START(list, aCount);
+ //
+ TInt* startPtr = reinterpret_cast<TInt*>(&list); // Same as list[0]
+ for(TInt i=0; i<aCount; i++)
+ {
+ const TInt cycle = startPtr[i];
+ aSkipArray.AppendL(cycle);
+ }
+ }
+
+
+static TInt RunOOMTestL(TGAFunction aFunction, const RArray<TInt>& aSkipArray)
+ {
+ //
+ TBool printedTestTitle = EFalse;
+ TInt ret = KErrNoMemory;
+ TInt failAt = 0;
+ while(ret != KErrNone)
+ {
+ failAt += failAt/50 + 1;
+ TheTest.Printf(_L("OOM step: %d\n"), failAt);
+ if (aSkipArray.Find(failAt) != KErrNotFound)
+ continue;
+ //
+ __UHEAP_MARK;
+ TheTestHelper->CreateDatabaseL();
+
+ __UHEAP_SETFAIL(RHeap::EDeterministic, failAt);
+ TRAP(ret, aFunction(printedTestTitle));
+ __UHEAP_RESET;
+
+ // Ensure that we close the database
+ TheTestHelper->CloseDatabase();
+
+
+ __UHEAP_MARKEND;
+ //
+ if (ret != KErrNoMemory && ret != KErrNone)
+ {
+ TheTest.Printf(_L("Non standard error: %d\n"),ret);
+ TheTest.Getch();
+ }
+ TheTest(ret == KErrNoMemory || ret == KErrNone);
+ }
+ //
+ return KErrNone;
+ }
+
+static void RunOOMTestsL()
+ {
+ ExpandCleanupStackL();
+ //
+ RArray<TInt> knownFailures;
+ CleanupClosePushL(knownFailures);
+
+ // EXPORT
+ PrepareTestSkipsL(knownFailures, 0);
+ RunOOMTestL(Test1L, knownFailures);
+ //
+ // (Skip OOM on Test2L, Test3L and Test4L as they execute the same code as Test1L)
+
+ // IMPORT
+ PrepareTestSkipsL(knownFailures, 0);
+ RunOOMTestL(Test5L, knownFailures);
+ //
+ // (Skip OOM on Test6L, Test7L and Test8L as they execute the same code as Test5L)
+
+ CleanupStack::PopAndDestroy(&knownFailures);
+ }
+#endif
+
+static void DoMainL()
+ {
+ CTestRegister* TempFiles = CTestRegister::NewLC();
+ TempFiles->RegisterL(KTestDatabaseFile, EFileTypeCnt);
+ TempFiles->RegisterL(KTestVCardExportFileName);
+ TempFiles->RegisterL(KTestVCardImportFileName);
+
+ // Run normal testing
+ TRAPD(testRet, RunTestsL());
+ TheTest(testRet == KErrNone);
+
+ // Run OOM testing
+#ifdef OOM_TESTS
+ TRAPD(oomRet, RunOOMTestsL());
+ TheTest(oomRet == KErrNone);
+#endif
+
+ CleanupStack::PopAndDestroy(TempFiles);
+ }
+
+/**
+
+@SYMTestCaseID PIM-T-GENERALADDRESS-0001
+
+*/
+
+GLDEF_C TInt E32Main()
+ {
+ __UHEAP_MARK;
+ TheTest.Start(_L("@SYMTESTCaseID:PIM-T-GENERALADDRESS-0001 T_GENERALADDRESS - Test General Address Export and Import"));
+
+
+ // Stupid test library alert...
+ TheTestHelper = new(ELeave) CCntTest();
+ TheTestHelper->ConstructL(TheTest, KTestDatabaseFile);
+
+ TRAP_IGNORE(DoMainL());
+ //
+ TheTestHelper->EndTestLib(KErrNone);
+ //
+ __UHEAP_MARKEND;
+ return(KErrNone);
+ }