--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines_old/contactsmodel/tsrc/T_FilteredViewEvents.cpp Fri Jun 11 13:29:23 2010 +0300
@@ -0,0 +1,664 @@
+// 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_FilteredViewEvents");
+
+_LIT(KTestDbName, "c:T_FilteredViewEvents.cdb");
+_LIT(KDbName,"c:ViewTest.db");
+_LIT(KViewName, "TestView");
+const TInt KNumOfContacts = 3;
+const TInt KTimeout = 60*1000000; // 60 seconds
+const TInt KTestBufSize = 64;
+const TContactViewPreferences KContactViewPrefs =
+static_cast<TContactViewPreferences>
+ ( EContactsOnly | EUnSortedAtEnd | ESingleWhiteSpaceIsEmptyField );
+
+
+LOCAL_D RTest test(KTestName);
+
+
+class CTestResources : public CBase
+ {
+ public:
+ static CTestResources* NewLC();
+ void ConstructL();
+ TContactItemId CreateTestContactL(const TDesC& aFamilyName, TBool aWithPhoneNumber);
+ ~CTestResources();
+
+ CContactDatabase* iDb;
+ TContactItemId iGroupId;
+ CContactDbEventQueue* iDbEventQueue;
+ CContactViewEventQueue* iViewEventQueue;
+ RContactViewSortOrder iViewSortOrder;
+ CContactLocalView* iLocalView;
+ CContactViewEventQueue* iFilteredViewEventQueue;
+ CContactFilteredView* iFilteredView;
+ TContactItemId iTestContactId;
+ };
+
+CTestResources* CTestResources::NewLC()
+ {
+ CTestResources* self = new(ELeave) CTestResources;
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+void CTestResources::ConstructL()
+ {
+ iDb = CContactDatabase::ReplaceL(KTestDbName);
+ iDbEventQueue = CContactDbEventQueue::NewL(iDb);
+
+ iViewEventQueue = CContactViewEventQueue::NewL();
+
+ iViewSortOrder.AppendL(KUidContactFieldFamilyName);
+ iViewSortOrder.AppendL(KUidContactFieldGivenName);
+ iViewSortOrder.AppendL(KUidContactFieldCompanyName);
+
+ iLocalView = CContactLocalView::NewL
+ (*iViewEventQueue, *iDb, iViewSortOrder, EContactsOnly);
+
+ iFilteredViewEventQueue = CContactViewEventQueue::NewL();
+ // Create a filtered view which contains contacts with phone numbers
+ iFilteredView = CContactFilteredView::NewL
+ (*iFilteredViewEventQueue, *iDb, *iLocalView, CContactDatabase::EPhonable);
+
+ // Wait for filtered view to get ready
+ TContactViewEvent event;
+ __ASSERT_ALWAYS(iFilteredViewEventQueue->ListenForEvent(10,event), User::Invariant());
+ __ASSERT_ALWAYS(event.iEventType == TContactViewEvent::EReady, User::Invariant());
+
+ // Flush all other events
+ iDbEventQueue->Flush();
+ iViewEventQueue->Flush();
+ iFilteredViewEventQueue->Flush();
+ }
+
+TContactItemId CTestResources::CreateTestContactL
+ (const TDesC& aFamilyName, TBool aWithPhoneNumber)
+ {
+ // 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
+ if (aWithPhoneNumber)
+ {
+ // Create a phone number field
+ CContactItemField* field = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldPhoneNumber);
+ field->TextStorage()->SetTextL(_L("555"));
+ card->AddFieldL(*field);
+ CleanupStack::Pop(field);
+ }
+ // 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;
+ return contactId;
+ }
+
+CTestResources::~CTestResources()
+ {
+ if (iFilteredView) iFilteredView->Close(*iFilteredViewEventQueue);
+ delete iFilteredViewEventQueue;
+ if (iLocalView) iLocalView->Close(*iViewEventQueue);
+ iViewSortOrder.Close();
+ delete iViewEventQueue;
+ delete iDbEventQueue;
+ delete iDb;
+ TRAP_IGNORE(CContactDatabase::DeleteDatabaseL(KTestDbName));
+ }
+
+LOCAL_C CTestResources* DoTestAddContactLC(TBool aWithPhoneNumber)
+ {
+ CTestResources* res = CTestResources::NewLC();
+
+ const TContactItemId contactId = res->CreateTestContactL(_L("Joplin"), aWithPhoneNumber);
+
+ // Check that iLocalView sends an event
+ TContactViewEvent event;
+ test(res->iViewEventQueue->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);
+
+ return res;
+ }
+
+
+//
+//
+class CFilteredViewTester : public CTimer, public MContactViewObserver
+{
+public:
+ static CFilteredViewTester* NewL();
+ ~CFilteredViewTester();
+ void StartTest();
+ TBool TestCompletedOk();
+
+private:
+ CFilteredViewTester();
+ void ConstructL();
+ void NextTestStepL();
+ void CreateViewsL();
+ void AddContactsL(TInt aCount);
+ void DeleteContactsDescL(TInt aCount);
+ TContactItemId DoAddContactL(TInt n);
+ CContactItemField* CreateFieldLC(const TUid aMappingUId, TFieldType aFieldType, const TDesC &aText);
+
+private: // from CTimer
+ void RunL();
+ void DoCancel();
+
+private: // from MContactViewObserver
+ void HandleContactViewEvent(const CContactViewBase &aView, const TContactViewEvent &aEvent);
+
+private:
+ enum TestStates{
+ EStateIdle = 0,
+ ECreateView,
+ EAddContacts,
+ EDeleteContacts,
+ ETestComplete,
+ };
+
+private:
+ TestStates iState;
+ CContactDatabase* iContactDb;
+ CContactViewBase* iBaseView;
+ CContactViewBase* iFilteredView;
+ TBool iBaseReady;
+ TBool iFilteredReady;
+ TInt iBaseContactsCount;
+ TInt iFilteredContactsCount;
+ RContactViewSortOrder iSortOrder;
+ CContactIdArray* iIdArray;
+ TBool iTimerStarted;
+ TInt iContactArrayIndex;
+ RArray<TInt>iPosition;
+};
+
+CFilteredViewTester* CFilteredViewTester::NewL()
+{
+ CFilteredViewTester* self = new (ELeave) CFilteredViewTester();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+}
+
+CFilteredViewTester::CFilteredViewTester()
+: CTimer(CActive::EPriorityStandard)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CFilteredViewTester::~CFilteredViewTester()
+ {
+ iPosition.Close();
+ iSortOrder.Close();
+ delete iIdArray;
+ if (iFilteredView)
+ {
+ iFilteredView->Close(*this);
+ }
+ if (iBaseView)
+ {
+ iBaseView->Close(*this);
+ }
+ delete iContactDb;
+ TRAP_IGNORE(CContactDatabase::DeleteDatabaseL(KDbName) );
+ }
+
+
+void CFilteredViewTester::ConstructL()
+ {
+ CTimer::ConstructL();
+ iContactDb = CContactDatabase::CreateL(KDbName);
+ iSortOrder.AppendL(KUidContactFieldFamilyName);
+ iSortOrder.AppendL(KUidContactFieldGivenName);
+ iIdArray = CContactIdArray::NewL ();
+ }
+
+void CFilteredViewTester::StartTest()
+ {
+ iState = ECreateView;
+ TRequestStatus* s = &iStatus;
+ User::RequestComplete(s, KErrNone);
+ SetActive();
+ }
+
+void CFilteredViewTester::NextTestStepL()
+ {
+ switch (iState)
+ {
+ case ECreateView:
+ CreateViewsL();
+ break;
+ case EAddContacts:
+ AddContactsL(KNumOfContacts);
+ break;
+ case EDeleteContacts:
+ DeleteContactsDescL(KNumOfContacts);
+ break;
+ case ETestComplete:
+ default:
+ TRequestStatus* s = &iStatus;
+ User::RequestComplete(s, KErrNone);
+ break;
+ }
+ }
+
+void CFilteredViewTester::RunL()
+ {
+ if (!iTimerStarted)
+ {
+ iTimerStarted = ETrue;
+ After(KTimeout);
+ NextTestStepL();
+ }
+ else
+ {
+ CActiveScheduler::Stop ();
+ }
+ }
+
+void CFilteredViewTester::DoCancel()
+ {
+ }
+
+TBool CFilteredViewTester::TestCompletedOk()
+ {
+ return iState == ETestComplete;
+ }
+
+void CFilteredViewTester::HandleContactViewEvent(const CContactViewBase& aView, const TContactViewEvent& aEvent)
+ {
+ switch (aEvent.iEventType)
+ {
+ case TContactViewEvent::EReady:
+ {
+ if (&aView == iBaseView)
+ {
+ iBaseReady = ETrue;
+ }
+ else if (&aView == iFilteredView)
+ {
+ iFilteredReady = ETrue;
+ }
+
+ if (iFilteredReady && iBaseReady && iState == ECreateView)
+ {
+ iState = EAddContacts;
+ TRAPD(err, NextTestStepL() );
+ test(err == KErrNone);
+ }
+ break;
+ }
+
+ case TContactViewEvent::EItemAdded:
+ {
+ if (&aView == iBaseView)
+ {
+ test.Printf(_L("Add event received: Base view\r\n"));
+ iBaseContactsCount++;
+ }
+ else if (&aView == iFilteredView)
+ {
+ iPosition.AppendL(aEvent.iInt);
+ test.Printf(_L("Add event received: Filtered view\r\n"));
+ iFilteredContactsCount++;
+ }
+ if (iBaseContactsCount == KNumOfContacts && iFilteredContactsCount == KNumOfContacts && iState == EAddContacts)
+ {
+ iState = EDeleteContacts;
+ NextTestStepL();
+ }
+ break;
+ }
+
+ case TContactViewEvent::EItemRemoved:
+ {
+ if (&aView == iBaseView)
+ {
+ test.Printf(_L("Remove event received: Base view\r\n"));
+ iBaseContactsCount--;
+ }
+ else if (&aView == iFilteredView)
+ {
+ test.Printf(_L("Remove event received: Filtered view\r\n"));
+ iFilteredContactsCount--;
+ //Verify that deleted contact is the one present in the event recieved.
+ //The order is not important.
+ TBool found = EFalse;
+ TInt count = iIdArray->Count();
+ for(TInt loop = 0; loop < count;++loop)
+ {
+ if(aEvent.iContactId == (*iIdArray)[loop])
+ {
+ found = ETrue;
+ break;
+ }
+ }
+ test(found);
+ //test that the underlying position is within the range of total number of contacts.
+ found = EFalse;
+ count = iPosition.Count();
+ for(TInt loop = 0; loop < count;++loop)
+ {
+ if(aEvent.iInt == iPosition[loop])
+ {
+ found = ETrue;
+ break;
+ }
+ }
+ test(found);
+ }
+
+ if (iBaseContactsCount == 0 && iFilteredContactsCount == 0 && iState == EDeleteContacts)
+ {
+ iState = ETestComplete;
+ NextTestStepL();
+ }
+ break;
+ }
+
+ default:
+ {
+ // do nothing...
+ break;
+ }
+ }
+ }
+
+void CFilteredViewTester::CreateViewsL()
+ {
+ iBaseView = CContactNamedRemoteView::NewL(*this, KViewName, *iContactDb, iSortOrder, KContactViewPrefs);
+ iFilteredView = CContactFilteredView::NewL(*this, *iContactDb, *iBaseView, CContactDatabase::EPhonable);
+ }
+
+void CFilteredViewTester::AddContactsL(TInt aCount)
+ {
+ for (TInt i = 0; i < aCount; ++i)
+ {
+ iIdArray->AddL(DoAddContactL(i));
+ }
+ }
+
+void CFilteredViewTester::DeleteContactsDescL(TInt aCount)
+ {
+ for (TInt i = aCount - 1; i >= 0; --i)
+ {
+ iContactDb->DeleteContactL((*iIdArray)[i]);
+ }
+ }
+
+TContactItemId CFilteredViewTester::DoAddContactL(TInt aOrdinal)
+ {
+ TBuf<KTestBufSize> name(_L("MyContact"));
+ TBuf<KTestBufSize> num1(_L("123456"));
+ TBuf<KTestBufSize> num2(_L("123457"));
+ name.AppendNum (aOrdinal);
+ num1.AppendNum (aOrdinal);
+ num2.AppendNum (aOrdinal);
+
+ CContactCard* card = CContactCard::NewLC();
+
+ card->AddFieldL(*CreateFieldLC(KUidContactFieldVCardMapUnusedN, KUidContactFieldGivenName, _L("ContactField")));
+ CleanupStack::Pop();
+ card->AddFieldL (*CreateFieldLC(KUidContactFieldVCardMapUnusedN, KUidContactFieldFamilyName, name));
+ CleanupStack::Pop();
+ card->AddFieldL (*CreateFieldLC(KUidContactFieldVCardMapTEL, KUidContactFieldPhoneNumber, num1));
+ CleanupStack::Pop();
+ card->AddFieldL (*CreateFieldLC(KUidContactFieldVCardMapTELFAX, KUidContactFieldPhoneNumber, num2));
+ CleanupStack::Pop();
+
+ TContactItemId id = iContactDb->AddNewContactL(*card);
+ CleanupStack::PopAndDestroy(card);
+ return id;
+ }
+
+CContactItemField* CFilteredViewTester::CreateFieldLC(const TUid aMappingUId, TFieldType aFieldType, const TDesC &aText)
+ {
+ CContactItemField * field =CContactItemField::NewLC(KStorageTypeText, aFieldType);
+ field->SetMapping(aMappingUId);
+ field->TextStorage()->SetTextL(aText);
+ return field;
+ }
+// CFilteredViewTester
+//
+
+LOCAL_C void TestAddContactWithPhoneNumberL()
+ {
+ test.Next(_L("Add a contact with phone number"));
+
+ CTestResources* res = DoTestAddContactLC(ETrue);
+
+ // There should come an event from iFilteredView because the added
+ // contact matches the filtering criteria
+ TContactViewEvent event;
+ test(res->iFilteredViewEventQueue->ListenForEvent(10,event));
+ test(event.iEventType == TContactViewEvent::EItemAdded);
+ test(event.iContactId == res->iTestContactId);
+ test(event.iInt >= 0 && event.iInt < res->iFilteredView->CountL());
+ test(res->iFilteredView->AtL(event.iInt) == res->iTestContactId);
+
+ CleanupStack::PopAndDestroy(res);
+ }
+
+LOCAL_C void TestRemoveContactWithPhoneNumberL()
+ {
+ test.Next(_L("Remove a contact with phone number"));
+
+ CTestResources* res = DoTestAddContactLC(ETrue);
+
+ // There should come an event from iFilteredView because the added
+ // contact matches the filtering criteria
+ TContactViewEvent viewEvent;
+ test(res->iFilteredViewEventQueue->ListenForEvent(10,viewEvent));
+ test(viewEvent.iEventType == TContactViewEvent::EItemAdded);
+ test(viewEvent.iContactId == res->iTestContactId);
+ test(viewEvent.iInt >= 0 && viewEvent.iInt < res->iFilteredView->CountL());
+ test(res->iFilteredView->AtL(viewEvent.iInt) == res->iTestContactId);
+
+ // Delete the added contact
+ res->iDb->DeleteContactL(res->iTestContactId);
+
+ // Wait for a DB event
+ TContactDbObserverEvent dbEvent;
+ test(res->iDbEventQueue->ListenForEvent(10,dbEvent));
+ test(dbEvent.iType == EContactDbObserverEventContactDeleted);
+ test(dbEvent.iContactId == res->iTestContactId);
+
+ // Check that iLocalView sends an event
+ test(res->iViewEventQueue->ListenForEvent(10,viewEvent));
+ test(viewEvent.iEventType == TContactViewEvent::EItemRemoved);
+ test(viewEvent.iContactId == res->iTestContactId);
+ test(viewEvent.iInt >= 0 && viewEvent.iInt <= res->iLocalView->CountL());
+ test(res->iLocalView->FindL(viewEvent.iContactId) == KErrNotFound);
+
+ // There should come an event from iFilteredView because the added
+ // contact matches the filtering criteria
+ test(res->iFilteredViewEventQueue->ListenForEvent(10,viewEvent));
+ test(viewEvent.iEventType == TContactViewEvent::EItemRemoved);
+ test(viewEvent.iContactId == res->iTestContactId);
+ test(viewEvent.iInt >= 0 && viewEvent.iInt <= res->iFilteredView->CountL());
+ test(res->iFilteredView->FindL(viewEvent.iContactId) == KErrNotFound);
+
+ CleanupStack::PopAndDestroy(res);
+ }
+
+
+LOCAL_C void TestAddContactWithoutPhoneNumberL()
+ {
+ test.Next(_L("Add a contact without phone number"));
+
+ CTestResources* res = DoTestAddContactLC(EFalse);
+
+ // There shouldn't come any event from iFilteredView because the added
+ // contact does not match the filtering criteria.
+ // However, if an event is received check that it is valid
+ TContactViewEvent event;
+ if (res->iFilteredViewEventQueue->ListenForEvent(10,event))
+ {
+ test(event.iEventType == TContactViewEvent::EItemAdded);
+ test(event.iContactId == res->iTestContactId);
+ test(event.iInt >= 0 && event.iInt < res->iFilteredView->CountL());
+ test(res->iFilteredView->AtL(event.iInt) == res->iTestContactId);
+ }
+ CleanupStack::PopAndDestroy(res);
+ }
+
+LOCAL_C void TestRemoveContactWithoutPhoneNumberL()
+ {
+ test.Next(_L("Remove a contact without phone number"));
+
+ CTestResources* res = DoTestAddContactLC(EFalse);
+
+ // There shouldn't come any event from iFilteredView because the added
+ // contact does not match the filtering criteria.
+ // However, if an event is received check that it is valid
+ TContactViewEvent viewEvent;
+ if (res->iFilteredViewEventQueue->ListenForEvent(10,viewEvent))
+ {
+ // Already tested in TestAddContactWithoutPhoneNumberL
+ /*
+ test(viewEvent.iEventType == TContactViewEvent::EItemAdded);
+ test(viewEvent.iContactId == res->iTestContactId);
+ test(viewEvent.iInt >= 0 && viewEvent.iInt < res->iFilteredView->CountL());
+ test(res->iFilteredView->AtL(viewEvent.iInt) == res->iTestContactId);
+ */
+ }
+
+ // Delete the added contact
+ res->iDb->DeleteContactL(res->iTestContactId);
+
+ // Wait for a DB event
+ TContactDbObserverEvent dbEvent;
+ test(res->iDbEventQueue->ListenForEvent(10,dbEvent));
+ test(dbEvent.iType == EContactDbObserverEventContactDeleted);
+ test(dbEvent.iContactId == res->iTestContactId);
+
+ // Check that iLocalView sends an event
+ test(res->iViewEventQueue->ListenForEvent(10,viewEvent));
+ test(viewEvent.iEventType == TContactViewEvent::EItemRemoved);
+ test(viewEvent.iContactId == res->iTestContactId);
+ test(viewEvent.iInt >= 0 && viewEvent.iInt <= res->iLocalView->CountL());
+ test(res->iLocalView->FindL(viewEvent.iContactId) == KErrNotFound);
+
+ // There shouldn't come any event from iFilteredView because the removed
+ // contact does not match the filtering criteria.
+ // However, if an event is sent check that it is valid
+ if (res->iFilteredViewEventQueue->ListenForEvent(10,viewEvent))
+ {
+ test(viewEvent.iEventType == TContactViewEvent::EItemRemoved);
+ test(viewEvent.iContactId == res->iTestContactId);
+ test(viewEvent.iInt >= 0 && viewEvent.iInt <= res->iFilteredView->CountL());
+ test(res->iFilteredView->FindL(viewEvent.iContactId) == KErrNotFound);
+ }
+ CleanupStack::PopAndDestroy(res);
+ }
+
+
+LOCAL_C void TestListenForRemoveContactEventsL()
+ {
+ test.Next(_L("Check events received when deleting contacts"));
+
+
+ CFilteredViewTester* viewTest = CFilteredViewTester::NewL();
+ CleanupStack::PushL(viewTest);
+
+ viewTest->StartTest();
+ CActiveScheduler::Start();
+
+ test(viewTest->TestCompletedOk());
+
+ CleanupStack::PopAndDestroy(viewTest);
+ }
+
+/**
+
+@SYMTestCaseID PIM-T-FILTEREDVIEWEVENTS-0001
+
+*/
+
+void DoTestsL()
+ {
+ test.Start(_L("@SYMTESTCaseID:PIM-T-FILTEREDVIEWEVENTS-0001 T_FilteredViewEvents"));
+
+
+ TestAddContactWithPhoneNumberL();
+ TestRemoveContactWithPhoneNumberL();
+ TestAddContactWithoutPhoneNumberL();
+ TestRemoveContactWithoutPhoneNumberL();
+ TestListenForRemoveContactEventsL();
+
+ 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;
+ }