pimprotocols/phonebooksync/Test/TE_cntsync/te_cntsyncutils.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 14 Sep 2010 20:54:53 +0300
branchRCL_3
changeset 21 9da50d567e3c
parent 0 e686773b3f54
permissions -rw-r--r--
Revision: 201033 Kit: 201035

// 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:
//

#include "te_cntsyncutils.h"
#include "te_cntsyncbase.h"

/** 
 * Factory construction method.
 * @return Pointer to CPhbkDeleteIntegrationTest object
 */
CPhbkIntegrationTestUtility* CPhbkIntegrationTestUtility::NewL()
	{
	CPhbkIntegrationTestUtility* self = new(ELeave) CPhbkIntegrationTestUtility();
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop();
	return self;
	}

/** Destructor. */
CPhbkIntegrationTestUtility::~CPhbkIntegrationTestUtility()
	{
	iSession.Close();
	delete iDb;
	}

/** 
 * Second-phase constructor.
 * This is required because the SIM test configuration must be set before
 * the CSimPhone is constructed.
 */
void CPhbkIntegrationTestUtility::ConstructL()
	{
	User::LeaveIfError(iSession.Connect());
	User::After(3000000); // wait for session to startup

	//
	// Attempt to open the Contacts DB up to three times.
	//
	TInt  err(KErrNone);

	for (TInt count = 0;  count < 3;  count++)
		{
		TRAP(err, iDb = CContactDatabase::OpenL());
		if (err != KErrLocked)
			{
			break;
			}

		if (count + 1 < 3)
			{
			User::After(1000000);
			}
		}
	User::LeaveIfError(err);
	User::After(3000000); // wait for session to startup
	}

/** Default constructor */
CPhbkIntegrationTestUtility::CPhbkIntegrationTestUtility()
	{
	}


/** 
 * Check group membership.
 * All ICC entries synchronised should belong to a single group. This group 
 * should contain all the ADN phonebook entries
 *
 * @param aItem             ICC entry 
 * @param aExpectedMembers  Expected number of members of the ADN phonebook
 */
void CPhbkIntegrationTestUtility::CheckGroupMembershipL(CContactICCEntry& aItem, TInt aExpectedMembers)
	{
	const CContactIdArray* owned = aItem.GroupsJoined();	
	__ASSERT_ALWAYS(owned != NULL, User::Leave(EFail));
	__ASSERT_ALWAYS(owned->Count() == 1, User::Leave(EFail));
	TContactItemId groupId = (*owned)[0];

	CContactGroup* group = static_cast<CContactGroup*>(iDb->ReadContactLC(groupId));
	const CContactIdArray* itemsContained = group->ItemsContained();
	__ASSERT_ALWAYS(itemsContained->Count() == aExpectedMembers, User::Leave(EFail));
	CleanupStack::PopAndDestroy(group);	
	}

/** 
 * Check that the field of type aFieldType has the same content as 
 * aExpectedContent
 * @param aFieldset Contact item fieldset
 * @param aFieldType Field type to test
 * @param aExpectedContent Expected data
 */
void CPhbkIntegrationTestUtility::CheckFieldContentL(CContactItemFieldSet& aFieldset, TFieldType aFieldType, const TDesC& aExpectedContent)
	{
	TInt pos = aFieldset.Find(aFieldType);
	CContactItemField& field = aFieldset[pos];
	CContactTextField* textField = field.TextStorage();
	__ASSERT_ALWAYS(textField != NULL, User::Leave(EFail));
	__ASSERT_ALWAYS(textField->Text() == aExpectedContent, User::Leave(EFail));
	}

/** 
 * Check that aEntry contains correct number of fields.
 *
 * @param aPhonebook  ICC Phonebook to check.
 * @param aEntry      Contact ICC Entry
 */
void CPhbkIntegrationTestUtility::CheckFieldCountL(const TUid aPhonebook, CContactICCEntry* aEntry)
	{
	CContactItemFieldSet& fieldset = aEntry->CardFields();
	const TInt fieldsetCount = fieldset.Count(); //for debugging
	if ((aPhonebook == KUidUsimAppAdnPhonebook) || (aPhonebook == KUidIccGlobalAdnPhonebook))
		{
		__ASSERT_ALWAYS(fieldsetCount >= 6, User::Leave(EFail)); //Name,Number,email,ICC slot, phonebook
		}
	else
		{
		__ASSERT_ALWAYS(fieldsetCount == 5, User::Leave(EFail)); //Name,Number,ICC slot, phonebook
		}
	}

/** 
 * Check that aEntry contains correct number of fields for minimal contact item.
 *
 * @param aPhonebook  ICC Phonebook to check.
 * @param aEntry      Contact ICC Entry
 */
void CPhbkIntegrationTestUtility::CheckMinimalFieldCountL(const TUid aPhonebook, CContactICCEntry* aEntry)
	{
	CContactItemFieldSet& fieldset = aEntry->CardFields();
	const TInt fieldsetCount = fieldset.Count(); //for debugging
	if (aPhonebook == KUidUsimAppAdnPhonebook)
		{
		__ASSERT_ALWAYS(fieldsetCount >= 5, User::Leave(EFail)); //Name,Number,email,ICC slot, phonebook
		}
	else
		{
		__ASSERT_ALWAYS(fieldsetCount == 4, User::Leave(EFail)); //Name,Number,ICC slot, phonebook
		}
	}

/** 
 * Check that the field data stored on the SIM is identical to the
 * data stored in Contacts model.
 * @param aItem ICC item to test
 * @param aSlotNumber Slot number 
 */
void CPhbkIntegrationTestUtility::CheckFieldsL(CContactICCEntry& aItem, TInt aSlotNumber)
	{
	TBuf<20> buf;
	CContactItemFieldSet& fieldset = aItem.CardFields();
	buf.Format(KNameFormat,aSlotNumber);
	CheckFieldContentL(fieldset,KUidContactFieldFamilyName,buf);
	buf.Format(KNumberFormat,aSlotNumber);
	CheckFieldContentL(fieldset,KUidContactFieldPhoneNumber,buf);
	}

/** 
 * Read an ICC entry - normal case.
 * Check group membership is correct and correct number of fields have
 * been created.
 */
void CPhbkIntegrationTestUtility::ReadContactL(const TUid aPhonebook, TInt aExpectedCount)
	{
	iDb->SetDbViewContactType(KUidContactICCEntry);
	// get the unique groupId for the given phonebook
	TContactItemId groupId(KNullContactId);
	User::LeaveIfError(iSession.GetPhoneBookId(groupId, 
						RPhoneBookSession::ESyncGroupId,
						aPhonebook));
	__ASSERT_ALWAYS(groupId != KNullContactId, User::Leave(EFail));
  
	// based on the groupId, get items belonging to the phonebook
	CContactGroup* group = NULL;
	TRAPD(err, group = static_cast<CContactGroup*>(iDb->ReadContactL(groupId)));
	__ASSERT_ALWAYS(err == KErrNone, User::Leave(EFail));
	CleanupStack::PushL(group);
	const CContactIdArray* array = group->ItemsContained();

	// Verify correct number of entries created for this phonebook
	TInt count = array->Count(); // for debugging
	__ASSERT_ALWAYS(count == aExpectedCount, User::Leave(EFail));

	// Read all items
	for (TInt i=0; i<count; ++i)
		{
		TContactItemId id = (*array)[i];
		CContactICCEntry* entry = NULL;
		TRAP(err, entry = static_cast<CContactICCEntry*>(iDb->ReadContactL(id)));
		__ASSERT_ALWAYS(err == KErrNone, User::Leave(EFail));
		CleanupStack::PushL(entry);
		// Verify correct number of fields created for entry
		CheckFieldCountL(aPhonebook, entry);
		CleanupStack::PopAndDestroy(); // entry
		}

	CleanupStack::PopAndDestroy(); // group

	}

/**
 * Read an ICC contact - minimal read operation.
 */
void CPhbkIntegrationTestUtility::ReadMinimalContactL(const TUid aPhonebook, TInt aExpectedCount)
	{
	iDb->SetDbViewContactType(KUidContactICCEntry);
	// get the unique groupId for the given phonebook
	TContactItemId groupId(KNullContactId);
	User::LeaveIfError(iSession.GetPhoneBookId(groupId, 
						RPhoneBookSession::ESyncGroupId,
						aPhonebook));
	__ASSERT_ALWAYS(groupId != KNullContactId, User::Leave(EFail));
  
	// based on the groupId, get items belonging to the phonebook
	CContactGroup* group = NULL;
	TRAPD(err, group = static_cast<CContactGroup*>(iDb->ReadContactL(groupId)));
	__ASSERT_ALWAYS(err == KErrNone, User::Leave(EFail));
	CleanupStack::PushL(group);
	const CContactIdArray* array = group->ItemsContained();

	// Verify correct number of entries created for this phonebook
	const TInt count = array->Count(); // for debugging
	__ASSERT_ALWAYS(count == aExpectedCount, User::Leave(EFail));

	// Read entry
	TContactItemId id((*array)[0]);
	CContactICCEntry* entry = static_cast<CContactICCEntry*>(iDb->ReadMinimalContactL(id));
	CleanupStack::PushL(entry);
	CheckFieldCountL(aPhonebook, entry); // Entry contains correct number of fields

	CleanupStack::PopAndDestroy(2); // group & entry
	}

/** 
 * Add a contact to the ICC & database.
 * @param aName Name
 * @param aNumber Phone number
 * @param aPhonebook Phonebook UID (optional)
 * @param aEmail Email entry (optional)
 */
void CPhbkIntegrationTestUtility::AddContactL(const TDesC& aName, const TDesC& aNumber, const TUid aPhonebook, const TDesC& aEmail)
	{
	TContactItemId templateId(iDb->ICCTemplateIdL(aPhonebook));
	CContactItem* iccTemplate = iDb->ReadContactLC(templateId);
	CContactICCEntry* entry = CContactICCEntry::NewL(*iccTemplate);
	CleanupStack::PopAndDestroy(iccTemplate);
	CleanupStack::PushL(entry);
	//Set the phonebook field, if the field doesn't exist, it should be added
	CContactItemFieldSet& fieldset = entry->CardFields();
	TInt n = fieldset.Find(KUidContactFieldICCPhonebook);
	if(n==KErrNotFound)
		{
		CContactItemField* field = CContactItemField::NewLC(KStorageTypeText,KUidContactFieldICCPhonebook);
		entry->AddFieldL(*field);
		CleanupStack::Pop(field);
		CContactItemFieldSet& fieldset = entry->CardFields();
		n = fieldset.Find(KUidContactFieldICCPhonebook);
		__ASSERT_ALWAYS(n != KErrNotFound, User::Leave(EFail));
		}
	CContactItemField& field = fieldset[n];
	CContactTextField* textField = field.TextStorage();
	TBuf<128> buf;
	TInt phonebookUidNum = aPhonebook.iUid;
	buf.AppendNum(phonebookUidNum);
	textField->SetTextL(buf);

	AddTextFieldL(KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,aName,*entry);
	AddTextFieldL(KUidContactFieldPhoneNumber,KUidContactFieldVCardMapTEL,aNumber,*entry);
	if (aPhonebook == KUidUsimAppAdnPhonebook)
		{
		AddTextFieldL(KUidContactFieldEMail,KUidContactFieldVCardMapUnusedN,aEmail,*entry);
		}
	TContactItemId id(iDb->AddNewContactL(*entry)); 
	CleanupStack::PopAndDestroy(entry);	
	__ASSERT_ALWAYS(id != KNullContactId, User::Leave(EFail));
	}

/** 
 * Add a contact to the ICC & database.
 * @param aName Name
 * @param aNumber Phone number
 * @param aSlotNumber Slot number
 * @param aPhonebook Phonebook UID (optional)
 * @param aEmail Email entry (optional)
 */
void CPhbkIntegrationTestUtility::AddContactL(const TDesC& aName, const TDesC& aNumber, const TDesC& aSlotNumber, const TUid aPhonebook, const TDesC& aEmail)
	{
	TContactItemId templateId(iDb->ICCTemplateIdL(aPhonebook));
	CContactItem* iccTemplate = iDb->ReadContactLC(templateId);
	CContactICCEntry* entry = CContactICCEntry::NewL(*iccTemplate);
	CleanupStack::PopAndDestroy(iccTemplate);
	CleanupStack::PushL(entry);
	//Set the phonebook field, if the field doesn't exist, it should be added
	CContactItemFieldSet& fieldset = entry->CardFields();
	TInt n = fieldset.Find(KUidContactFieldICCPhonebook);
	if(n==KErrNotFound)
		{
		CContactItemField* field = CContactItemField::NewLC(KStorageTypeText,KUidContactFieldICCPhonebook);
		entry->AddFieldL(*field);
		CleanupStack::Pop(field);
		CContactItemFieldSet& fieldset = entry->CardFields();
		n = fieldset.Find(KUidContactFieldICCPhonebook);
		__ASSERT_ALWAYS(n != KErrNotFound, User::Leave(EFail));
		}
	CContactItemField& field = fieldset[n];
	CContactTextField* textField = field.TextStorage();
	TBuf<128> buf;
	TInt phonebookUidNum = aPhonebook.iUid;
	buf.AppendNum(phonebookUidNum);
	textField->SetTextL(buf);

	AddTextFieldL(KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,aName,*entry);
	AddTextFieldL(KUidContactFieldPhoneNumber,KUidContactFieldVCardMapTEL,aNumber,*entry);
	AddTextFieldL(KUidContactFieldICCSlot,KUidContactFieldVCardMapTEL,aSlotNumber,*entry);
	if (aPhonebook == KUidUsimAppAdnPhonebook)
		{
		AddTextFieldL(KUidContactFieldEMail,KUidContactFieldVCardMapUnusedN,aEmail,*entry);
		}
	TContactItemId id(iDb->AddNewContactL(*entry)); 
	CleanupStack::PopAndDestroy(entry);	
	__ASSERT_ALWAYS(id != KNullContactId, User::Leave(EFail));
	}

/**
 * Add a new text field (aField) to the CContactICCEntry supplied by aIccEntry. 
 * @param aFieldType Field type
 * @param aMapping Mapping for the field's content type
 * @param aField Field data
 * @param aIccEntry CContactICCEntry item
 */ 
void CPhbkIntegrationTestUtility::AddTextFieldL(TFieldType aFieldType, TUid aMapping, const TDesC& aField, CContactICCEntry& aIccEntry)
	{
	CContactItemFieldSet& fieldSet = aIccEntry.CardFields();
	TInt pos = fieldSet.Find(aFieldType);
	if (pos!=KErrNotFound)
		{
		CContactItemField& field=fieldSet[pos];
		field.TextStorage()->SetTextL(aField);
		}
	else
		{
		CContactItemField* field=CContactItemField::NewLC(KStorageTypeText, aFieldType);
		field->SetMapping(aMapping);
		field->AddFieldTypeL(aFieldType); 
		field->TextStorage()->SetTextL(aField);
		aIccEntry.AddFieldL(*field);
		CleanupStack::Pop(field); 
		}
	}

/** Delete an ICC contact - normal case */
void CPhbkIntegrationTestUtility::DeleteContactL(const TUid aPhonebook, TInt aIndex)
	{
	iDb->SetDbViewContactType(KUidContactICCEntry);
	// get the unique groupId for the given phonebook
	TContactItemId groupId(KNullContactId);
	User::LeaveIfError(iSession.GetPhoneBookId(groupId, 
						RPhoneBookSession::ESyncGroupId,
						aPhonebook));
	__ASSERT_ALWAYS(groupId != KNullContactId, User::Leave(EFail));
  
	// based on the groupId, get items belonging to the phonebook
	CContactGroup* group = NULL;
	TRAPD(err, group = static_cast<CContactGroup*>(iDb->ReadContactL(groupId)));
	__ASSERT_ALWAYS(err == KErrNone, User::Leave(EFail));
	CleanupStack::PushL(group);
	const CContactIdArray* array = group->ItemsContained();

	// delete item
	TInt count = array->Count();
	__ASSERT_ALWAYS(count >= aIndex, User::Leave(EFail));
	TContactItemId id = (*array)[aIndex];
	iDb->DeleteContactL(id);

	//check the item has been removed from the database
	CContactItem* item=NULL; 
	TRAP(err, item = iDb->ReadContactL(id)); 
	__ASSERT_ALWAYS(err == KErrNotFound, User::Leave(EFail));
	delete item;

	CleanupStack::PopAndDestroy(); // group
	}

/** 
 * Find contact IDs that match aFindString in the field specified by aFieldToSearch.
 * @param aFindString Text to search for
 * @param aFieldToSearch Field to search
 * @param aExpectedMatches Expected number of matching contacts
 */
void CPhbkIntegrationTestUtility::FindContactsL(const TDesC& aFindString, TFieldType aFieldToSearch, TInt aExpectedMatches)
	{
	CContactItemFieldDef* fieldDef=new(ELeave) CContactItemFieldDef;
	CleanupStack::PushL(fieldDef);
	fieldDef->AppendL(aFieldToSearch);
	CContactIdArray* array = iDb->FindLC(aFindString,fieldDef);
	__ASSERT_ALWAYS(array->Count() == aExpectedMatches, User::Leave(EFail));
	CleanupStack::PopAndDestroy(2,fieldDef);
	}

/** 
 * Replace the current name field with another name
 * @param aItem Reference to CContactItem
 * @param aModifiedName New name to use
 */
void CPhbkIntegrationTestUtility::ChangeNameFieldL(CContactItem& aItem, const TDesC& aModifiedName)
	{
	CContactItemFieldSet& fieldset = aItem.CardFields();
	const TInt pos(fieldset.Find(KUidContactFieldFamilyName));	
	CContactItemField& field = fieldset[pos];
	CContactTextField* textfield = field.TextStorage();
	textfield->SetTextL(aModifiedName);
	}

/** 
 * Replace the current name field with another name
 * @param aItem Reference to CContactItem
 * @param aModifiedNumber New number to use
 */
void CPhbkIntegrationTestUtility::ChangeNumberFieldL(CContactItem& aItem, const TDesC& aModifiedNumber)
	{
	CContactItemFieldSet& fieldset = aItem.CardFields();
	const TInt pos(fieldset.Find(KUidContactFieldPhoneNumber));
	CContactItemField& field = fieldset[pos];
	CContactTextField* textfield = field.TextStorage();
	textfield->SetTextL(aModifiedNumber);
	}

/** Open an ICC contact for edit */
void CPhbkIntegrationTestUtility::OpenContactL()
	{
	iDb->SetDbViewContactType(KUidContactICCEntry);
	const CContactIdArray* sortedItems = iDb->SortedItemsL();
	TContactItemId id = (*sortedItems)[0];
	CContactICCEntry* entry = static_cast<CContactICCEntry*>(iDb->OpenContactLX(id));
	CleanupStack::PushL(entry);
	ChangeNameFieldL(*entry,KModifiedName);
	iDb->CloseContactL(id);
	CleanupStack::PopAndDestroy(2); //entry+lockrecord
	}

/** Edit an ICC contact */
void CPhbkIntegrationTestUtility::EditContactL()
	{
	iDb->SetDbViewContactType(KUidContactICCEntry);
	const CContactIdArray* sortedItems = iDb->SortedItemsL();
	TContactItemId id = (*sortedItems)[0];
	CContactICCEntry* entry = static_cast<CContactICCEntry*>(iDb->OpenContactLX(id));
	CleanupStack::PushL(entry);
	ChangeNameFieldL(*entry,KModifiedName);
	iDb->CommitContactL(*entry);
	CleanupStack::PopAndDestroy(2); //entry+lockrecord
	}