phonebookengines/contactsmodel/tsrc/T_ContactViewEvents.cpp
changeset 0 e686773b3f54
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/T_ContactViewEvents.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,979 @@
+// 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 <e32test.h>
+#include <cntdef.h>
+#include <cntdb.h>
+#include <cntitem.h>
+#include <cntfield.h>
+#include <cntfldst.h>
+#include <cntviewbase.h>
+
+#include "CContactViewEventQueue.h"
+#include "CContactDbEventQueue.h"
+
+_LIT(KTestName, "T_GroupViewEvents");
+
+_LIT(KTestDbName, "c:T_GroupViewEvents.cdb");
+
+_LIT(KTestGrpName, "T_Group");
+
+_LIT(KRemoteView, "Test_UnderlyingRemoteView");
+
+LOCAL_D RTest test(KTestName);
+
+class CTestResources : public CBase
+    {
+    public:
+        static CTestResources* NewLC(TBool aShowContactInGrp);
+        static CTestResources* NewLC(TBool aShowContactInGrp, TBool aUnderlyingRemoteView);
+        void ConstructL(TBool aUnderlinedRemoteView = EFalse);
+        TContactItemId CreateTestContactL(const TDesC& aFamilyName);
+        ~CTestResources();
+
+        CContactDatabase* iDb;
+        CContactDbEventQueue* iDbEventQueue;
+        CContactViewEventQueue* iLocalViewEventQueue;
+        CContactViewEventQueue* iRemoteViewEventQueue;
+        RContactViewSortOrder iViewSortOrder;
+        CContactLocalView* iLocalView;
+        CContactNamedRemoteView* iRemoteView;
+        
+        CContactViewEventQueue* iOldAPIGroupViewEventQueue;
+        CContactViewEventQueue* iOldAPIFindViewEventQueue;   
+        CContactViewEventQueue* iOldAPISubViewEventQueue;
+        
+        CContactViewEventQueue* iNewAPIGroupViewEventQueue;
+        CContactViewEventQueue* iNewAPIFindViewEventQueue;
+        CContactViewEventQueue* iNewAPISubViewEventQueue;
+        
+        CContactGroupView* iGroupViewOldAPI;
+        CContactFindView* iFindViewOldAPI;
+        CContactSubView* iSubViewOldAPI;
+        
+        CContactGroupView* iGroupViewNewAPI;
+        CContactFindView* iFindViewNewAPI;
+        CContactSubView* iSubViewNewAPI;
+
+        CContactIdArray* iContactIdArray;
+        TContactItemId iTestContactId;
+        TContactItemId iGrpId;
+        
+        TBool		   iShowContactInGrp;
+    private:
+  	    CTestResources(TBool aShowContactInGrp);
+    
+    };
+
+CTestResources::CTestResources(TBool aShowContactInGrp)
+	: iShowContactInGrp(aShowContactInGrp)
+	{
+	}
+
+CTestResources* CTestResources::NewLC(TBool aShowContactInGrp)
+    {
+    CTestResources* self = new(ELeave) CTestResources(aShowContactInGrp);
+    
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;
+    }	
+    
+CTestResources* CTestResources::NewLC(TBool aShowContactInGrp, TBool aUnderlyingRemoteView)
+	{
+	if(aUnderlyingRemoteView == EFalse)
+		{
+		return NewLC(aShowContactInGrp);
+		}
+	
+	CTestResources* self = new(ELeave) CTestResources(aShowContactInGrp);
+	CleanupStack::PushL(self);
+	self->ConstructL(ETrue);
+	return self;
+	}        
+
+void CTestResources::ConstructL(TBool aUnderlinedRemoteView)
+    {
+    iDb = CContactDatabase::ReplaceL(KTestDbName);
+    iDbEventQueue = CContactDbEventQueue::NewL(iDb);
+   
+    iViewSortOrder.AppendL(KUidContactFieldFamilyName);
+    iViewSortOrder.AppendL(KUidContactFieldGivenName);
+    iViewSortOrder.AppendL(KUidContactFieldCompanyName);
+    
+    iContactIdArray = CContactIdArray::NewL();
+    
+    CContactItem* grpItem = iDb->CreateContactGroupL(KTestGrpName);
+    iGrpId = grpItem->Id();
+    delete grpItem;
+    
+	if(aUnderlinedRemoteView == EFalse)
+	{
+		iLocalViewEventQueue = CContactViewEventQueue::NewL();
+		iLocalView = CContactLocalView::NewL
+			(*iLocalViewEventQueue, *iDb, iViewSortOrder, EContactsOnly);
+		}
+	else
+		{
+		iRemoteViewEventQueue = CContactViewEventQueue::NewL();
+		iRemoteView = CContactNamedRemoteView::NewL
+			(*iRemoteViewEventQueue, KRemoteView, *iDb, iViewSortOrder, EContactsOnly); 
+		}
+
+    iOldAPIGroupViewEventQueue = CContactViewEventQueue::NewL();
+    
+    CContactGroupView::TGroupType grpType = iShowContactInGrp ? 
+    										CContactGroupView::EShowContactsInGroup : 
+    										CContactGroupView::EShowContactsNotInAnyGroup;
+    
+    CContactViewBase* underlyingView = aUnderlinedRemoteView?(static_cast<CContactViewBase*>(iRemoteView)):(static_cast<CContactViewBase*>(iLocalView)); //do not take the ownership
+    // Create a group view to test old functionality/API
+    iGroupViewOldAPI = CContactGroupView::NewL(*iDb, *underlyingView, *iOldAPIGroupViewEventQueue, KTestGrpName, grpType);
+        
+	iOldAPIFindViewEventQueue = CContactViewEventQueue::NewL();
+	CPtrCArray* findWordArray = new (ELeave) CPtrCArray(1);
+	findWordArray->AppendL(_L(""));
+	// Create a find view to test old functionality/API
+	iFindViewOldAPI = CContactFindView::NewL(*iDb, *underlyingView, *iOldAPIFindViewEventQueue, findWordArray);
+
+	iOldAPISubViewEventQueue = CContactViewEventQueue::NewL();
+	// Create a sub view to test old functionality/API
+	iSubViewOldAPI = CContactSubView::NewL(*iOldAPISubViewEventQueue,*iDb, *underlyingView,_L(">a"), _L("<z"));	
+		
+	iNewAPIGroupViewEventQueue = CContactViewEventQueue::NewL();
+    // Create a group view to test new functionality/API
+    iGroupViewNewAPI = CContactGroupView::NewL(*underlyingView, *iDb, *iNewAPIGroupViewEventQueue, KTestGrpName, grpType);
+
+	iNewAPIFindViewEventQueue = CContactViewEventQueue::NewL();
+	// Create a find view to test the new functionality/API 
+	iFindViewNewAPI = CContactFindView::NewL(*underlyingView, *iDb, *iNewAPIFindViewEventQueue, findWordArray);
+		
+	iNewAPISubViewEventQueue = CContactViewEventQueue::NewL();
+	// Create a sub view to test old functionality/API
+	iSubViewNewAPI = CContactSubView::NewL(*underlyingView, *iDb, *iNewAPISubViewEventQueue, _L(">a"), _L("<z"));
+
+	
+	findWordArray->Reset();
+	delete findWordArray;
+
+    // Wait for contact views derived classes to get ready
+    TContactViewEvent event;
+    if(aUnderlinedRemoteView == EFalse)
+    	{
+    	__ASSERT_ALWAYS(iOldAPIGroupViewEventQueue->ListenForEvent(10,event), User::Invariant());
+    	__ASSERT_ALWAYS(event.iEventType == TContactViewEvent::EReady, User::Invariant());
+    	__ASSERT_ALWAYS(iOldAPIFindViewEventQueue->ListenForEvent(10,event), User::Invariant());
+    	__ASSERT_ALWAYS(event.iEventType == TContactViewEvent::EReady, User::Invariant());
+    	__ASSERT_ALWAYS(iOldAPISubViewEventQueue->ListenForEvent(10,event), User::Invariant());
+    	__ASSERT_ALWAYS(event.iEventType == TContactViewEvent::EReady, User::Invariant());
+
+    	__ASSERT_ALWAYS(iNewAPIGroupViewEventQueue->ListenForEvent(10,event), User::Invariant());
+    	__ASSERT_ALWAYS(event.iEventType == TContactViewEvent::EReady, User::Invariant());
+    	__ASSERT_ALWAYS(iNewAPIFindViewEventQueue->ListenForEvent(10,event), User::Invariant());
+    	__ASSERT_ALWAYS(event.iEventType == TContactViewEvent::EReady, User::Invariant());
+    	__ASSERT_ALWAYS(iNewAPISubViewEventQueue->ListenForEvent(10,event), User::Invariant());
+    	__ASSERT_ALWAYS(event.iEventType == TContactViewEvent::EReady, User::Invariant());
+    	}
+
+    // Flush all other events
+    iDbEventQueue->Flush();
+    if(aUnderlinedRemoteView == EFalse)
+    	{
+    	iLocalViewEventQueue->Flush();
+    	}
+    else
+    	{
+    	iRemoteViewEventQueue->Flush();
+    	}
+    
+    iOldAPIGroupViewEventQueue->Flush();
+    iOldAPIFindViewEventQueue->Flush();
+    iOldAPISubViewEventQueue->Flush();
+    
+    iNewAPIGroupViewEventQueue->Flush();
+    iNewAPIFindViewEventQueue->Flush();
+    iNewAPISubViewEventQueue->Flush();
+    }
+
+TContactItemId CTestResources::CreateTestContactL(const TDesC& aFamilyName)
+    {
+    // Create a contact card
+    CContactCard* card = CContactCard::NewLC();
+    // Create a name field
+    CContactItemField* field = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldFamilyName);
+    field->TextStorage()->SetTextL(aFamilyName);
+    card->AddFieldL(*field);
+    CleanupStack::Pop(field);
+    // Create a phone number field
+    CContactItemField* phoneField = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldPhoneNumber);
+    phoneField->TextStorage()->SetTextL(_L("555"));
+    card->AddFieldL(*phoneField);
+    CleanupStack::Pop(phoneField);
+    
+    // Add the contact to the DB
+    const TContactItemId contactId = iDb->AddNewContactL(*card);
+    CleanupStack::PopAndDestroy(card);
+	    
+    // Eat away contact db events
+    TContactDbObserverEvent event;
+    while 
+        (iDbEventQueue->ListenForEvent(10,event) && 
+        (event.iType != EContactDbObserverEventContactAdded ||
+        event.iContactId != contactId))
+        {
+        }
+    iTestContactId = contactId;
+    
+    if(iShowContactInGrp)
+    	{
+	   	iDb->AddContactToGroupL(contactId, iGrpId);
+    	}
+
+    return contactId;
+    }
+
+CTestResources::~CTestResources()
+    {
+    if (iGroupViewOldAPI) 
+    	iGroupViewOldAPI->Close(*iOldAPIGroupViewEventQueue);
+    delete iOldAPIGroupViewEventQueue;
+
+    if (iFindViewOldAPI)
+    	iFindViewOldAPI->Close(*iOldAPIFindViewEventQueue);
+    delete iOldAPIFindViewEventQueue;
+    
+    if (iSubViewOldAPI)
+    	iSubViewOldAPI->Close(*iOldAPISubViewEventQueue);
+    delete iOldAPISubViewEventQueue;
+    
+    if (iGroupViewNewAPI) 
+    	iGroupViewNewAPI->Close(*iNewAPIGroupViewEventQueue);
+    delete iNewAPIGroupViewEventQueue;
+
+    if (iFindViewNewAPI)
+    	iFindViewNewAPI->Close(*iNewAPIFindViewEventQueue);
+    delete iNewAPIFindViewEventQueue;
+
+    if (iSubViewNewAPI)
+    	iSubViewNewAPI->Close(*iNewAPISubViewEventQueue);
+    delete iNewAPISubViewEventQueue;
+    
+    if (iLocalView) 
+    	iLocalView->Close(*iLocalViewEventQueue);
+    delete iLocalViewEventQueue;
+     
+    if (iRemoteView)	
+    	iRemoteView->Close(*iRemoteViewEventQueue);
+    delete iRemoteViewEventQueue;	
+    
+    iContactIdArray->Reset();
+    delete iContactIdArray;
+    
+    iViewSortOrder.Close(); 
+    delete iDbEventQueue;
+    delete iDb;
+    TRAP_IGNORE(CContactDatabase::DeleteDatabaseL(KTestDbName));
+    }
+
+LOCAL_C CTestResources* DoTestAddContactAPILC(TBool aShowContactInGrp)
+    {
+    //add 2 contacts and check if localview send events
+    CTestResources* res = CTestResources::NewLC(aShowContactInGrp);
+    
+    const TContactItemId contactId = res->CreateTestContactL(_L("Example1"));
+    res->iContactIdArray->AddL(contactId);
+
+    // Check that iLocalView sends an event
+    TContactViewEvent event;
+    test(res->iLocalViewEventQueue->ListenForEvent(10,event));
+    test(event.iEventType == TContactViewEvent::EItemAdded);
+    test(event.iContactId == contactId);
+    test(event.iInt == 0 && event.iInt < res->iLocalView->CountL());
+    test(res->iLocalView->AtL(event.iInt) == res->iTestContactId);
+	
+	if(aShowContactInGrp)
+		{
+	    test(res->iLocalViewEventQueue->ListenForEvent(10,event));
+	    test(event.iEventType == TContactViewEvent::EGroupChanged);
+	    test(event.iContactId == res->iGrpId);
+		}
+
+    const TContactItemId contactId1 = res->CreateTestContactL(_L("Example2"));
+    res->iContactIdArray->AddL(contactId1);
+
+    //get the EItemAdd event
+    test(res->iLocalViewEventQueue->ListenForEvent(10,event));
+    test(event.iEventType == TContactViewEvent::EItemAdded);
+    test(event.iContactId == contactId1);
+    test(event.iInt == 1);
+    test(res->iLocalView->AtL(event.iInt) == res->iTestContactId);
+
+	if(aShowContactInGrp)
+		{
+	    test(res->iLocalViewEventQueue->ListenForEvent(10,event));
+	    test(event.iEventType == TContactViewEvent::EGroupChanged);
+	    test(event.iContactId == res->iGrpId);
+		}
+		
+    return res;
+    }
+
+
+LOCAL_C void TestAddContactOldAPIL(TBool aShowContactInGrp)
+    {
+    test.Next(_L("Add a contact with phone number - old api"));
+
+    CTestResources* res = DoTestAddContactAPILC(aShowContactInGrp);
+
+    TContactViewEvent event;
+
+	for(int i = 0; i < 2; i++)
+		{
+	    // There should come EItemAdded event from group view - check if iInt is the right one
+	    test(res->iOldAPIGroupViewEventQueue->ListenForEvent(10,event));
+	    test(event.iEventType == TContactViewEvent::EItemAdded);
+	    test(event.iInt == 0);
+	    
+	    if(aShowContactInGrp)
+	    	{
+		    //Consume add to group event
+		    test(res->iOldAPIGroupViewEventQueue->ListenForEvent(10,event));
+	    	}
+					
+		// There should come EItemAdded event from find view - check if iInt is the right one
+	    test(res->iOldAPIFindViewEventQueue->ListenForEvent(10,event));
+	    test(event.iEventType == TContactViewEvent::EItemAdded);
+	    test(event.iInt == 0);
+	    
+	    if(aShowContactInGrp)
+	    	{
+		    //Consume add to group event
+		    test(res->iOldAPIFindViewEventQueue->ListenForEvent(10,event));
+	    	}
+	    	
+		// There should come EItemAdded event from sub view - check if iInt is the right one
+	    test(res->iOldAPISubViewEventQueue->ListenForEvent(10,event));
+	    test(event.iEventType == TContactViewEvent::EItemAdded);
+	    test(event.iInt == 0);
+
+	    if(aShowContactInGrp)
+	    	{
+		    //Consume add to group event
+		    test(res->iOldAPISubViewEventQueue->ListenForEvent(10,event));
+	    	}
+		}
+    CleanupStack::PopAndDestroy(res);
+    }
+
+
+LOCAL_C void TestRemoveContactOldAPIL(TBool aShowContactInGrp)
+    {
+    test.Next(_L("Remove a contact with phone number - old api"));
+
+    CTestResources* res = DoTestAddContactAPILC(aShowContactInGrp);
+	
+    TContactViewEvent viewEvent;
+    
+    int factor = aShowContactInGrp? 2 : 1;
+    
+    // first comsume the add events from group view, find view and sub view
+    for(int i = 0; i < 2 * factor; i++)
+    	{
+	    test(res->iOldAPIGroupViewEventQueue->ListenForEvent(10,viewEvent));
+	    test(res->iOldAPIFindViewEventQueue->ListenForEvent(10,viewEvent));
+	    test(res->iOldAPISubViewEventQueue->ListenForEvent(10,viewEvent));
+    	}
+	
+    // Delete the last added contact
+    res->iDb->DeleteContactL(res->iTestContactId);
+
+    // Wait for a DB event
+    TContactDbObserverEvent dbEvent;
+    if(aShowContactInGrp)
+    	{
+	    test(res->iDbEventQueue->ListenForEvent(10,dbEvent));
+	    test(dbEvent.iType == EContactDbObserverEventGroupChanged);
+    	}
+    
+    test(res->iDbEventQueue->ListenForEvent(10,dbEvent));
+    test(dbEvent.iType == EContactDbObserverEventContactDeleted);
+    test(dbEvent.iContactId == res->iTestContactId);
+
+    // Check that iLocalView sends an event
+    test(res->iLocalViewEventQueue->ListenForEvent(10,viewEvent));
+    test(viewEvent.iEventType == TContactViewEvent::EItemRemoved);
+    test(viewEvent.iContactId == res->iTestContactId);
+    test(viewEvent.iInt == 1);
+    test(res->iLocalView->FindL(viewEvent.iContactId) == KErrNotFound);
+
+    // There should come events from group view - check if iInt is the right one
+    test(res->iOldAPIGroupViewEventQueue->ListenForEvent(10,viewEvent));
+    test(viewEvent.iEventType == TContactViewEvent::EItemRemoved);
+    test(viewEvent.iContactId == res->iTestContactId);
+    test(viewEvent.iInt == 1);
+    test(res->iGroupViewOldAPI->FindL(viewEvent.iContactId) == KErrNotFound);
+    
+    // There should come events from find view - check if iInt is the right one
+    test(res->iOldAPIFindViewEventQueue->ListenForEvent(10,viewEvent));
+    test(viewEvent.iEventType == TContactViewEvent::EItemRemoved);
+    test(viewEvent.iContactId == res->iTestContactId);
+    test(viewEvent.iInt == 0);
+    test(res->iGroupViewOldAPI->FindL(viewEvent.iContactId) == KErrNotFound);
+    
+    // There should come events from sub view - check if iInt is the right one
+    test(res->iOldAPISubViewEventQueue->ListenForEvent(10,viewEvent));
+    test(viewEvent.iEventType == TContactViewEvent::EItemRemoved);
+    test(viewEvent.iContactId == res->iTestContactId);
+    test(viewEvent.iInt == 0);
+    test(res->iGroupViewOldAPI->FindL(viewEvent.iContactId) == KErrNotFound);
+    
+    CleanupStack::PopAndDestroy(res);
+    }
+
+LOCAL_C void TestAddContactNewAPIL(TBool aShowContactInGrp)
+    {
+    test.Next(_L("Add a contact with phone number - new api"));
+
+    CTestResources* res = DoTestAddContactAPILC(aShowContactInGrp);
+
+    TContactViewEvent event;
+    
+	for(int i = 0; i < 2; i++)
+		{
+	    // There should come EItemAdded event from group view - check if iInt is the right one
+	    if(aShowContactInGrp)
+	    	{
+		    //Consume add to group event
+		    test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10,event));
+		    test(event.iEventType == TContactViewEvent::ESortOrderChanged);
+	    	}
+	    else //TO_FIX
+	    	{
+		    test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10,event));
+		    test(event.iEventType == TContactViewEvent::EItemAdded);
+		    test(event.iInt == i); 
+	    	}	
+	    
+					
+		// There should come EItemAdded event from find view - check if iInt is the right one
+	    test(res->iNewAPIFindViewEventQueue->ListenForEvent(10,event));
+	    test(event.iEventType == TContactViewEvent::EItemAdded);
+	    test(event.iInt == i); 
+	    
+	    if(aShowContactInGrp)
+	    	{
+		    //Consume add to group event
+		    test(res->iNewAPIFindViewEventQueue->ListenForEvent(10,event));
+		    test(event.iEventType == TContactViewEvent::EGroupChanged);
+	    	}
+	    
+	    	
+		// There should come EItemAdded event from sub view - check if iInt is the right one
+	    test(res->iNewAPISubViewEventQueue->ListenForEvent(10,event));
+	    test(event.iEventType == TContactViewEvent::EItemAdded);
+	    test(event.iInt == i); 
+	    if(aShowContactInGrp)
+	    	{
+		    //Consume add to group event
+		    test(res->iNewAPISubViewEventQueue->ListenForEvent(10,event));
+		    test(event.iEventType == TContactViewEvent::EGroupChanged);
+	    	}
+
+		}
+    CleanupStack::PopAndDestroy(res);
+    }
+
+
+LOCAL_C void TestRemoveContactNewAPIL(TBool aShowContactInGrp)
+    {
+    test.Next(_L("Remove a contact with phone number - new api"));
+
+    CTestResources* res = DoTestAddContactAPILC(aShowContactInGrp);
+    
+    TContactViewEvent viewEvent;
+    
+    // first comsume the add events from group view, find view and sub view
+	res->iNewAPIGroupViewEventQueue->Flush();
+	res->iNewAPIFindViewEventQueue->Flush();
+	res->iNewAPISubViewEventQueue->Flush();
+	
+    // Delete the last added contact
+    res->iDb->DeleteContactL(res->iTestContactId);
+
+    // Wait for a DB event
+    TContactDbObserverEvent dbEvent;
+    if(aShowContactInGrp)
+    	{
+	    test(res->iDbEventQueue->ListenForEvent(10,dbEvent));
+	    test(dbEvent.iType == EContactDbObserverEventGroupChanged);
+    	}
+    	
+    test(res->iDbEventQueue->ListenForEvent(10,dbEvent));
+    test(dbEvent.iType == EContactDbObserverEventContactDeleted);
+    test(dbEvent.iContactId == res->iTestContactId);
+
+    // Check that iLocalView sends an event
+    test(res->iLocalViewEventQueue->ListenForEvent(10,viewEvent));
+    test(viewEvent.iEventType == TContactViewEvent::EItemRemoved);
+    test(viewEvent.iContactId == res->iTestContactId);
+    test(viewEvent.iInt == 1);
+    test(res->iLocalView->FindL(viewEvent.iContactId) == KErrNotFound);
+
+    // There should come events from group view - check if iInt is the right one
+    test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10,viewEvent));
+    test(viewEvent.iEventType == TContactViewEvent::EItemRemoved);
+    test(viewEvent.iContactId == res->iTestContactId);
+    test(viewEvent.iInt == 1);
+    test(res->iGroupViewOldAPI->FindL(viewEvent.iContactId) == KErrNotFound);
+    
+    // There should come events from find view - check if iInt is the right one
+    test(res->iNewAPIFindViewEventQueue->ListenForEvent(10,viewEvent));
+    test(viewEvent.iEventType == TContactViewEvent::EItemRemoved);
+    test(viewEvent.iContactId == res->iTestContactId);
+    test(viewEvent.iInt == 1);
+    test(res->iGroupViewOldAPI->FindL(viewEvent.iContactId) == KErrNotFound);
+    
+    // There should come events from sub view - check if iInt is the right one
+    test(res->iNewAPISubViewEventQueue->ListenForEvent(10,viewEvent));
+    test(viewEvent.iEventType == TContactViewEvent::EItemRemoved);
+    test(viewEvent.iContactId == res->iTestContactId);
+    test(viewEvent.iInt == 1);
+    test(res->iGroupViewOldAPI->FindL(viewEvent.iContactId) == KErrNotFound);
+
+    CleanupStack::PopAndDestroy(res);
+    }
+    
+/*
+This function checks that for multiple deletes using the DeleteContactsL api, this generates
+an EUnavailable event before sending EItemRemoved events to signify that the views are 
+not synchronised yet. When the views are synchronised then a final EReady event is sent
+and all the views should then be consistent. All the subviews also receive the EUnavailable
+and EReady events.
+*/    
+
+
+LOCAL_C void TestRemoveContactsNewAPIL(TBool aShowContactInGrp)
+    {
+	test.Next(_L("Remove multiple contacts with phone number - new api"));
+
+    CTestResources* res = DoTestAddContactAPILC(aShowContactInGrp);
+   
+    TContactViewEvent viewEvent;
+    
+    // first consume the add events from group view, find view and sub view
+	res->iNewAPIGroupViewEventQueue->Flush();
+	res->iNewAPIFindViewEventQueue->Flush();
+	res->iNewAPISubViewEventQueue->Flush();
+	
+    // Delete multiple contacts, there are two in the array
+    res->iDb->DeleteContactsL(*(res->iContactIdArray));
+    
+    
+    //Check that the view has not been updated yet after the delete
+    TInt groupViewCount = res->iGroupViewNewAPI->CountL();
+    test(groupViewCount == 2);
+    TInt contactViewBaseContactId = res->iGroupViewNewAPI->AtL(0);
+    const CViewContact &vcontact = res->iGroupViewNewAPI->ContactAtL(0);
+    
+
+    // Wait for a DB event
+    TContactDbObserverEvent dbEvent;
+    
+	test(res->iDbEventQueue->ListenForEvent(10,dbEvent));
+	test(res->iDbEventQueue->ListenForEvent(10,dbEvent));
+	test(dbEvent.iType == EContactDbObserverEventUnknownChanges); 	
+
+    // Check that iLocalView sends an event
+	test(res->iLocalViewEventQueue->ListenForEvent(10,viewEvent));
+	test(viewEvent.iEventType == TContactViewEvent::EUnavailable);
+	test(res->iLocalViewEventQueue->ListenForEvent(10,viewEvent));
+	test(viewEvent.iEventType == TContactViewEvent::EReady);
+    
+
+    // There should be events from the group view - check if iInt is the right one
+    test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10,viewEvent));
+    test(viewEvent.iEventType == TContactViewEvent::EUnavailable);
+    test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10,viewEvent));
+    test(viewEvent.iEventType == TContactViewEvent::EItemRemoved);
+    test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10,viewEvent));
+    test(viewEvent.iEventType == TContactViewEvent::EItemRemoved);
+    test(viewEvent.iContactId == res->iTestContactId);
+    test(viewEvent.iInt == 0);
+   
+	test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10,viewEvent));
+	test(viewEvent.iEventType == TContactViewEvent::EReady);
+   
+    
+    // The group view should be consistent, there should be no contacts in this view
+    groupViewCount = res->iGroupViewNewAPI->CountL();
+    test(groupViewCount == 0);
+    // should not be able to find anything 
+    TRAPD(err, contactViewBaseContactId = res->iGroupViewNewAPI->AtL(0));
+    test(err == KErrNotFound);
+    
+    
+    
+    // Check that the find view receives its events
+    if(aShowContactInGrp)
+    	{
+	    test(res->iNewAPIFindViewEventQueue->ListenForEvent(10,viewEvent));
+	    test(viewEvent.iEventType == TContactViewEvent::EUnavailable);
+	    test(res->iNewAPIFindViewEventQueue->ListenForEvent(10,viewEvent));
+	    test(viewEvent.iEventType == TContactViewEvent::EReady);
+    	}
+    	 
+  
+    // Check that the subview event queue receives events correctly
+    if(aShowContactInGrp)
+    	{
+	    test(res->iNewAPISubViewEventQueue->ListenForEvent(10,viewEvent));
+	    test(viewEvent.iEventType == TContactViewEvent::EUnavailable);
+	    test(res->iNewAPISubViewEventQueue->ListenForEvent(10,viewEvent));
+	    test(viewEvent.iEventType == TContactViewEvent::EReady);
+    	}
+    test.Next(_L("Remove multiple contacts with phone number - new api Successfull"));
+	CleanupStack::PopAndDestroy(res);
+	}
+
+/*
+This function checks that for multiple deletes using the DeleteContactL api, EItemRemoved 
+events are sent in the right order and with the right info. A remote view is used
+*/
+
+
+LOCAL_C void TestRemoveContactRemoteViewNewAPIL(TBool aShowContactInGrp)
+{
+	test.Next(_L("Remote view - delete multiple contacts - new api"));
+
+    CTestResources* res = CTestResources::NewLC(aShowContactInGrp, ETrue);
+    TContactViewEvent viewEvent;
+    
+    CContactIdArray* idArray = CContactIdArray::NewLC();
+    // Create 4 contacts
+    for(TInt loop = 0; loop < 4; ++loop)
+    	{
+    	idArray->AddL(res->CreateTestContactL(_L("a")));
+    	}
+    
+    //just consume events
+    while(res->iRemoteViewEventQueue->ListenForEvent(1, viewEvent))
+    	{
+    	}
+    
+    // how many contacts do we have in remote view?
+	TInt remoteViewCount = res->iRemoteView->CountL();
+    test(remoteViewCount == 4);
+    
+    //delete all contacts now
+    for(TInt loop = 0; loop < idArray->Count(); ++loop)
+    	{
+    	res->iDb->DeleteContactL((*idArray)[loop]);
+    	}
+    
+    int currentEvent = 0;
+    // check incoming events
+    while(res->iRemoteViewEventQueue->ListenForEvent(1, viewEvent))
+    	{
+    	test(viewEvent.iEventType == TContactViewEvent::EItemRemoved);
+    	test(viewEvent.iInt == 0);
+    	test(viewEvent.iContactId == (*idArray)[currentEvent++]);
+    	}
+    
+    while(idArray->Count() > 0) 
+    	{
+    	idArray->Remove(0);
+    	}
+    
+    CleanupStack::PopAndDestroy(2, res);		
+	}
+
+LOCAL_C void SetTextFieldL(CContactItem& aItem, TUid aType, const TDesC& aValue)
+	{
+	CContactItemFieldSet& fieldSet = aItem.CardFields();
+	const TInt pos = fieldSet.Find(aType);
+	if(pos == KErrNotFound)
+		{
+		// if does not exist add this field
+		CContactItemField* field = CContactItemField::NewLC(KStorageTypeText, aType);
+		field->TextStorage()->SetTextL(aValue);
+		aItem.AddFieldL(*field);
+		CleanupStack::Pop(field);
+		}
+	else
+		{
+		fieldSet[pos].TextStorage()->SetTextL(aValue);
+		}
+	}
+
+
+LOCAL_C void TestSimulateSyncSessionL()
+    {
+	test.Next(_L("Simulate a sync session - 2 contacts changed - new api"));
+
+    CTestResources* res = CTestResources::NewLC(ETrue, ETrue);
+    TContactViewEvent viewEvent;
+    
+    // Create 2 contacts
+    TContactItemId firstContactId = res->CreateTestContactL(_L("ExampleA"));
+    TContactItemId secondContactId = res->CreateTestContactL(_L("ExampleB"));
+        
+	//we should have 5 events here
+	test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10,viewEvent));
+	test(viewEvent.iEventType == TContactViewEvent::EReady);
+	test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10,viewEvent));
+	test(viewEvent.iEventType == TContactViewEvent::EItemAdded);
+	test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10,viewEvent));
+	test(viewEvent.iEventType == TContactViewEvent::ESortOrderChanged);
+	test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10,viewEvent));
+	test(viewEvent.iEventType == TContactViewEvent::EItemAdded);
+	test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10,viewEvent));
+	test(viewEvent.iEventType == TContactViewEvent::ESortOrderChanged);
+
+	TInt groupViewCount = res->iGroupViewNewAPI->CountL();
+    test(groupViewCount == 2);
+            
+    // change existing contact items
+    CContactItem* firstContact = res->iDb->OpenContactL(firstContactId);
+    CleanupStack::PushL(firstContact);
+    CContactItem* secondContact = res->iDb->OpenContactL(secondContactId);
+    CleanupStack::PushL(secondContact);
+    
+    // change name
+    SetTextFieldL(*firstContact, KUidContactFieldFamilyName, _L("ExampleA1"));
+    SetTextFieldL(*secondContact, KUidContactFieldFamilyName, _L("1ExampleB"));
+
+	res->iNewAPIGroupViewEventQueue->Flush();
+	res->iNewAPIFindViewEventQueue->Flush();
+	res->iNewAPISubViewEventQueue->Flush();
+	
+    res->iDb->CommitContactL(*firstContact);	
+    res->iDb->CommitContactL(*secondContact);
+   
+    // check events and count in group view after these changes
+    test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10, viewEvent)); 
+    test(viewEvent.iEventType == TContactViewEvent::EItemRemoved); //first we should have a removed
+    test(res->iGroupViewNewAPI->CountL() == 1);
+    test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10, viewEvent)); 
+    test(viewEvent.iEventType == TContactViewEvent::EItemAdded); //then we should have an add
+    test(res->iGroupViewNewAPI->CountL() == 2);
+    test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10, viewEvent)); 
+    test(viewEvent.iEventType == TContactViewEvent::EItemRemoved); //then we should have a removed
+    test(res->iGroupViewNewAPI->CountL() == 1);
+    test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10, viewEvent)); 
+    test(viewEvent.iEventType == TContactViewEvent::EItemAdded); //then we should have an add
+    test(res->iGroupViewNewAPI->CountL() == 2);
+    
+    // check now the status of the group view - we should have 1Baname ; Apan1 in the group view
+    test(res->iGroupViewNewAPI->ContactAtL(0).Id() == secondContactId);
+    test(res->iGroupViewNewAPI->ContactAtL(1).Id() == firstContactId);
+    CleanupStack::PopAndDestroy(2, firstContact);
+    
+    // change back
+    firstContact = res->iDb->OpenContactL(firstContactId);
+    CleanupStack::PushL(firstContact);
+    secondContact = res->iDb->OpenContactL(secondContactId);
+    CleanupStack::PushL(secondContact);
+    // change back contacts
+    SetTextFieldL(*firstContact, KUidContactFieldFamilyName, _L("ExampleA"));
+    SetTextFieldL(*secondContact, KUidContactFieldFamilyName, _L("ExampleB"));
+    res->iDb->CommitContactL(*firstContact);	
+    res->iDb->CommitContactL(*secondContact);
+    //just consume events
+    while(res->iNewAPIGroupViewEventQueue->ListenForEvent(1, viewEvent))
+    	{
+    	}
+    // check now the status of the group view - we should have Apan ; Baname in the group view
+    test(res->iGroupViewNewAPI->ContactAtL(0).Id() == firstContactId);
+    test(res->iGroupViewNewAPI->ContactAtL(1).Id() == secondContactId);    
+    CleanupStack::PopAndDestroy(2, firstContact);
+    
+    // change again contacts but commit changes in different order
+    firstContact = res->iDb->OpenContactL(firstContactId);
+    CleanupStack::PushL(firstContact);
+    secondContact = res->iDb->OpenContactL(secondContactId);
+    CleanupStack::PushL(secondContact);
+    // change back contacts
+    SetTextFieldL(*firstContact, KUidContactFieldFamilyName, _L("ExampleA1"));
+    SetTextFieldL(*secondContact, KUidContactFieldFamilyName, _L("1ExampleB"));
+    res->iDb->CommitContactL(*firstContact);	
+    res->iDb->CommitContactL(*secondContact);
+    
+    // check events and count in group view after these changes
+    test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10, viewEvent)); 
+    test(viewEvent.iEventType == TContactViewEvent::EItemRemoved); //first we should have a removed
+    test(res->iGroupViewNewAPI->CountL() == 1);
+    test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10, viewEvent)); 
+    test(viewEvent.iEventType == TContactViewEvent::EItemAdded); //then we should have an add
+    test(res->iGroupViewNewAPI->CountL() == 2);
+    test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10, viewEvent)); 
+    test(viewEvent.iEventType == TContactViewEvent::EItemRemoved); //then we should have a removed
+    test(res->iGroupViewNewAPI->CountL() == 1);
+    test(res->iNewAPIGroupViewEventQueue->ListenForEvent(10, viewEvent)); 
+    test(viewEvent.iEventType == TContactViewEvent::EItemAdded); //then we should have an add
+    test(res->iGroupViewNewAPI->CountL() == 2);
+    // check now the status of the group view - we should have 1Baname ; Apan1 in the group view
+    test(res->iGroupViewNewAPI->ContactAtL(0).Id() == secondContactId);
+    test(res->iGroupViewNewAPI->ContactAtL(1).Id() == firstContactId);
+    
+    CleanupStack::PopAndDestroy(3, res);
+    }  
+
+
+LOCAL_C void TestSimulateSyncSession1L()
+    {
+	test.Next(_L("Simulate a sync session - 3 contacts changed - new api - new api"));
+
+    CTestResources* res = CTestResources::NewLC(ETrue, ETrue);
+    TContactViewEvent viewEvent;
+    
+    // Create 3 contacts
+    TContactItemId firstContactId = res->CreateTestContactL(_L("a"));
+    TContactItemId secondContactId = res->CreateTestContactL(_L("b"));
+    TContactItemId thirdContactId = res->CreateTestContactL(_L("c"));
+    
+    //just consume events
+    while(res->iNewAPIGroupViewEventQueue->ListenForEvent(10, viewEvent))
+    	{
+    	}
+    
+	TInt groupViewCount = res->iGroupViewNewAPI->CountL();
+    test(groupViewCount == 3);
+            
+    // change existing contact items
+    CContactItem* firstContact = res->iDb->OpenContactL(firstContactId);
+    CleanupStack::PushL(firstContact);
+    CContactItem* secondContact = res->iDb->OpenContactL(secondContactId);
+    CleanupStack::PushL(secondContact);
+    CContactItem* thirdContact = res->iDb->OpenContactL(thirdContactId);
+    CleanupStack::PushL(thirdContact);
+    
+    // change name
+    SetTextFieldL(*firstContact, KUidContactFieldFamilyName, _L("3a"));
+    SetTextFieldL(*secondContact, KUidContactFieldFamilyName, _L("2b"));
+    SetTextFieldL(*thirdContact, KUidContactFieldFamilyName, _L("1c"));
+
+	res->iNewAPIGroupViewEventQueue->Flush();
+	res->iNewAPIFindViewEventQueue->Flush();
+	res->iNewAPISubViewEventQueue->Flush();
+	
+    res->iDb->CommitContactL(*firstContact);	
+    res->iDb->CommitContactL(*secondContact);
+    res->iDb->CommitContactL(*thirdContact);
+
+    //just consume events
+    while(res->iNewAPIGroupViewEventQueue->ListenForEvent(1, viewEvent))
+    	{
+    	}
+
+     // check now the status of the group view - we should have 1c ; 2b ; 3a in the group view
+    test(res->iGroupViewNewAPI->ContactAtL(0).Id() == thirdContactId);
+    test(res->iGroupViewNewAPI->ContactAtL(1).Id() == secondContactId);
+    test(res->iGroupViewNewAPI->ContactAtL(2).Id() == firstContactId);
+    CleanupStack::PopAndDestroy(3, firstContact);
+    
+    //change back
+    firstContact = res->iDb->OpenContactL(firstContactId);
+    CleanupStack::PushL(firstContact);
+    secondContact = res->iDb->OpenContactL(secondContactId);
+    CleanupStack::PushL(secondContact);
+    thirdContact = res->iDb->OpenContactL(thirdContactId);
+    CleanupStack::PushL(thirdContact);
+    
+    // change name
+    SetTextFieldL(*firstContact, KUidContactFieldFamilyName, _L("a"));
+    SetTextFieldL(*secondContact, KUidContactFieldFamilyName, _L("b"));
+    SetTextFieldL(*thirdContact, KUidContactFieldFamilyName, _L("c"));
+
+    res->iDb->CommitContactL(*firstContact);	
+    res->iDb->CommitContactL(*secondContact);
+    res->iDb->CommitContactL(*thirdContact);
+
+    //just consume events
+    while(res->iNewAPIGroupViewEventQueue->ListenForEvent(1, viewEvent))
+    	{
+    	}
+
+     // check now the status of the group view - we should have a ; b ; c in the group view
+    test(res->iGroupViewNewAPI->ContactAtL(0).Id() == firstContactId);
+    test(res->iGroupViewNewAPI->ContactAtL(1).Id() == secondContactId);
+    test(res->iGroupViewNewAPI->ContactAtL(2).Id() == thirdContactId);
+    
+    CleanupStack::PopAndDestroy(4, res);
+    }
+
+/**
+
+@SYMTestCaseID     PIM-T-CONTACTVIEWEVENTS-0001
+
+*/
+
+void DoTestsL()
+    {
+	test.Start(_L("@SYMTESTCaseID:PIM-T-CONTACTVIEWEVENTS-0001 T_FilteredViewEvents"));
+
+	
+	//Test with contacts not in group
+    TestAddContactOldAPIL(EFalse);
+    TestRemoveContactOldAPIL(EFalse);
+    TestAddContactNewAPIL(EFalse);
+	TestRemoveContactNewAPIL(EFalse);
+	TestRemoveContactRemoteViewNewAPIL(EFalse);	
+	
+	//Test with contacts in group
+    TestAddContactOldAPIL(ETrue);
+    TestRemoveContactOldAPIL(ETrue);
+    TestAddContactNewAPIL(ETrue);
+	TestRemoveContactNewAPIL(ETrue);
+	TestRemoveContactRemoteViewNewAPIL(ETrue);	
+	
+	// remove multiple contacts
+	TestRemoveContactsNewAPIL(ETrue);
+	TestSimulateSyncSessionL();
+	TestSimulateSyncSession1L();
+	
+    test.End();
+    test.Close();
+
+    }
+
+GLDEF_C TInt E32Main()
+	{
+    // Init
+	__UHEAP_MARK;
+	
+    CTrapCleanup* cleanupStack = CTrapCleanup::New();
+    if (!cleanupStack)
+        {
+        return KErrNoMemory;
+        }
+
+    CActiveScheduler* activeScheduler = new CActiveScheduler;
+    if (!activeScheduler)
+        {
+        return KErrNoMemory;
+        }
+    CActiveScheduler::Install(activeScheduler);
+
+    // Run the tests
+    TRAPD(err, DoTestsL());
+
+    // Cleanup
+    delete activeScheduler;
+    delete cleanupStack;
+    
+   	__UHEAP_MARKEND;
+    	
+	return err;
+    }