--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/t_iccview.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,1239 @@
+// 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 <cntdb.h>
+#include <cntitem.h>
+#include <cntfield.h>
+#include <cntfldst.h>
+#include <e32math.h>
+#include <phbksync.h>
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include "cntsyncecom.h"
+#endif
+
+#include "T_UTILS.H"
+#include "cntsyncchecker.h"
+#include "CContactViewEventQueue.h"
+#include "CContactDbEventQueue.h"
+#include <ecom/ecom.h>
+// include templates for CleanupResetAndDestroyPushL(T)
+#include "cntviewprivate.h"
+
+_LIT(KTestName,"@SYMTestCaseID:PIM-T-ICCVIEW-0001 t_iccview");
+
+_LIT(KTestDbName, "c:T_ICCView.cdb");
+_LIT(KPluginName,"phone book synchronizer Implementation");
+_LIT(KTestPluginName,"Test phone book synchronizer Implementation");
+
+LOCAL_D RTest test(KTestName);
+
+LOCAL_D CContactSyncChecker* syncChecker;
+
+class CICCViewTest : public CBase
+ {
+public:
+ static CICCViewTest* NewLC(const RArray<TUid>& aPhonebookList);
+ ~CICCViewTest();
+
+ void TestOneOrFiveL(TBool aCreateViewBeforeSync);
+ void TestTwoL();
+ void TestThreeOrSixL(TBool aCreateViewBeforeSync);
+ void TestFourL();
+ void TestSevenL();
+ void TestConcurrenceL();
+
+private:
+ enum TSyncStatus
+ {
+ ENotSynchronised,
+ ESynchronised,
+ ESyncIccLocked,
+ };
+ CICCViewTest(const RArray<TUid>& aPhonebookList);
+ void ConstructL();
+
+ void CreateViewsL();
+ void CheckViewCreateAndSyncEventsL(TInt aSyncCompletionError, TInt aIsSyncError);
+ void CheckEventsForTestFourL();
+ void SyncThenCreateViewCheckEventsL(TInt aSyncCompletionError, TInt aIsSyncError);
+ void CheckEventsForTestSevenL();
+
+ void CreateEntriesL(TInt aNumberOfEntries, TBool aIsIccEntry=EFalse);
+ void CreateEntriesNoVerifyL(TInt aNumberOfEntries, TBool aIsIccEntry=EFalse);
+ void DeleteEntriesL(TInt aNumberOfEntries, TBool aIccEntry=EFalse);
+ void CreateEntryL(TBool aIsIccEntry=EFalse);
+ void VerifyNumberOfEntriesInEachViewL(TSyncStatus aSyncStatus);
+
+ void SetRandomAlphaString(TDes& aBuf,TInt aLength);
+ TText RandomCharCode(TText aLowerBound,TText aUpperBound,TText aException);
+ TText RandomCharCode(TText aLowerBound,TText aUpperBound);
+
+private:
+ const RArray<TUid>& iPhbkList;
+
+ CContactDatabase* iDb;
+ CContactItem* iEntry;
+ CContactViewEventQueue* iViewEventQueue;
+ RContactViewSortOrder iViewSortOrder;
+ CContactLocalView* iContactsView;
+ CContactLocalView* iIccView;
+ CContactLocalView* iContactsAndIccView;
+ CContactViewEventQueue* iFilteredViewEventQueue;
+ CContactItem* iTemplate;
+ RArray<TContactItemId> iIccContacts;
+ RArray<TContactItemId> iNonIccContacts;
+ TInt64 iRandSeed;
+
+ TInt iInitialIccCount;
+ };
+
+CICCViewTest* CICCViewTest::NewLC(const RArray<TUid>& aPhonebookList)
+ {
+ CICCViewTest* self = new(ELeave) CICCViewTest(aPhonebookList);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+CICCViewTest::CICCViewTest(const RArray<TUid>& aPhonebookList) : iPhbkList(aPhonebookList)
+ {
+ }
+
+void CICCViewTest::ConstructL()
+ {
+ // reset method call count & phonebook sync state
+ // Set-up responses from the phonebook plug-in
+ syncChecker->ResetEverythingL();
+
+ // tell phonebook sync simulator what phonebooks to use
+ test(syncChecker->SetPhonebookListL(iPhbkList) == KErrNone);
+ // put one contact in the first ICC Phonebook
+ test(syncChecker->AddContactToPhonebookL(iPhbkList[0], _L("John Brown"), _L("1234")) == KErrNone);
+ // put one contact in the last ICC Phonebook
+ test(syncChecker->AddContactToPhonebookL(iPhbkList[iPhbkList.Count()-1], _L("Al Capone"), _L("9876")) == KErrNone);
+ // number of ICC contacts expected in Views after Synchronisation
+ iInitialIccCount = 2;
+
+ // start test with empty database
+ iDb = CContactDatabase::ReplaceL(KTestDbName);
+
+ iViewEventQueue = CContactViewEventQueue::NewL();
+
+ iViewSortOrder.AppendL(KUidContactFieldFamilyName);
+ iViewSortOrder.AppendL(KUidContactFieldGivenName);
+ iViewSortOrder.AppendL(KUidContactFieldCompanyName);
+ }
+
+// Create 3 views: non-icc contacts, icc contacts, and both
+void CICCViewTest::CreateViewsL()
+ {
+ iContactsView = CContactLocalView::NewL(*iViewEventQueue, *iDb, iViewSortOrder, EContactsOnly);
+ iIccView = CContactLocalView::NewL(*iViewEventQueue, *iDb, iViewSortOrder, EICCEntriesOnly);
+ iContactsAndIccView = CContactLocalView::NewL(*iViewEventQueue, *iDb, iViewSortOrder, EICCEntriesAndContacts);
+ }
+
+/**
+ Test View notifications when Phonebook Synch finishes
+ Takes parameters to stimulate error conditions in the synchronisation
+
+ Method: Creates 3 views for Contacts, ICC Entries and Mixed Contacts & ICC Entries
+ Count/check the View events.
+ */
+void CICCViewTest::CheckViewCreateAndSyncEventsL(TInt aSyncCompletionError, TInt aIsSyncError)
+ {
+ // Wait for local views to get ready
+ TInt readyCount(0);
+ TInt sortErrorCount(0);
+ TContactViewEvent event;
+
+ // create the view to test
+ CreateViewsL();
+
+ // Contact only view should Ready
+ test(iViewEventQueue->ListenForEvent(10,event));
+
+ // Expecting EReady event
+ test.Printf(_L("Event received (%i)\n"), event.iEventType);
+ test(event.iEventType == TContactViewEvent::EReady);
+ readyCount++;
+
+ // there should be 1 Synch Change Notification request outstanding per phonebook
+ TInt notificationCount = syncChecker->TotalNotificationPendingCountL();
+ test(notificationCount == iPhbkList.Count());
+
+ // Phbk Watchers should be created when views were created - check number of plug-in calls
+ test(syncChecker->SyncMethodCallCountL() == (2 + 4 * iPhbkList.Count()));
+
+
+ // synchronise all phonebooks
+ test(syncChecker->SynchroniseIccAllPhonebooksL(*iDb, aSyncCompletionError, aIsSyncError) == KErrNone);
+
+
+ // views with ICC entries should become ready now
+ while (((readyCount + sortErrorCount) < 3) && iViewEventQueue->ListenForEvent(10,event))
+ {
+ // Expecting EReady events
+ switch (event.iEventType)
+ {
+ case TContactViewEvent::EItemAdded:
+ test.Printf(_L("Event received - EItemAdded\n"));
+ // ignore events from adding contacts
+ break;
+
+ case TContactViewEvent::EGroupChanged:
+ test.Printf(_L("Event received - EGroupChanged (group Id %i)\n"), event.iContactId);
+ // ignore events from adding contacts
+ break;
+
+ case TContactViewEvent::EReady:
+ test.Printf(_L("Event received - EReady\n"));
+ readyCount++;
+ break;
+
+ case TContactViewEvent::ESortError:
+ test.Printf(_L("Event received - ESortError\n"));
+ if (aSyncCompletionError != KErrNone)
+ {
+ test(event.iInt == aSyncCompletionError);
+ }
+ else
+ {
+ test(event.iInt == aIsSyncError);
+ }
+ sortErrorCount++;
+ break;
+
+ default:
+ test.Printf(_L("Unexpected event received (%i)\n"), event.iEventType);
+ test(0);
+ }
+ }
+
+ // either received all events or timed out waiting
+ if (aSyncCompletionError == KErrNone && aIsSyncError == KErrNone)
+ {
+ // all 3 views should be ready
+ test(readyCount == 3);
+
+ // check number of entries in views (ICC is synchronised)
+ VerifyNumberOfEntriesInEachViewL(ESynchronised);
+ }
+ else
+ {
+ // ICC views should have had sort errors
+ test(sortErrorCount == 2);
+
+ // check number of entries in views (ICC is not synchronised)
+ VerifyNumberOfEntriesInEachViewL(ENotSynchronised);
+ }
+
+
+ // there should be 1 Synch Change Notification request outstanding per phonebook
+ notificationCount = syncChecker->TotalNotificationPendingCountL();
+ test(notificationCount == iPhbkList.Count());
+
+ // Check the number of requests made to the plug-in
+ const TInt methodCount = syncChecker->SyncMethodCallCountL();
+ if (aSyncCompletionError == KErrNone)
+ {
+ // There should be 1 call plus 4 per phonebook to the Phonebook Sync plug-in
+ // PhonebookList + N * 2 * (NotifySyncStateChange, IsSynchronised)
+ test(methodCount == 2 + (8 * iPhbkList.Count()));
+ }
+ else
+ {
+ // There should be 1 call plus 2 per phonebook to the Phonebook Sync plug-in
+ // PhonebookList + N * (NotifySyncStateChange, IsSynchronised, NotifySyncStateChange)
+ test(methodCount == 2 + (6 * iPhbkList.Count()));
+ }
+
+
+ // Flush all other events
+ iViewEventQueue->Flush();
+ }
+
+
+/**
+ Test Objective: Test Phonebook Synch for SIM card that starts Locked and becomes Unlocked.
+ - tests View events and number of contacts in views
+
+ Method: Creates 3 views for Contacts, ICC Entries and Mixed Contacts & ICC Entries.
+ Simulated Phonebook Synch fails with ICC card locked, subsequently card becomes unlocked
+ and Phonebook Synch succeeds.
+
+ Test steps:
+ 1. Create some non-ICC Contacts.
+ 2. Contacts only view becomes ready, while PhoneBook Synch waits to Synchronise.
+ 3. PhoneBook Synch then indicates an error due to SIM card (ICC) locked.
+ 4. The two ICC views become available without ICC entries.
+ 5. The PhoneBook Synch then indicates that the Cache is Valid.
+ 6. The two ICC views are updated (re-sorted) with the ICC entries.
+ 7. Cleanup (deletes all entries)
+ */
+void CICCViewTest::CheckEventsForTestFourL()
+ {
+ // Wait for local views to get ready
+ TContactViewEvent event;
+ TInt readyCount(0);
+ TInt unavailableCount(0);
+ TInt sortOrderChangedCount(0);
+
+ // create the view to test
+ CreateViewsL();
+
+
+ // Test Step 1. Create some non-ICC Contacts.
+ test.Printf(_L("Creating 5 Contacts\n"));
+ CreateEntriesNoVerifyL(5);
+
+ // This While loop tests for steps:
+ // 2. Contacts only view becomes ready, while PhoneBook Synch waits to Synchronise.
+ // 3. PhoneBook Synch then indicates an error due to SIM card (ICC) locked.
+ // 4. The two ICC views become available without ICC entries.
+
+ /* Expected events:
+ * a) EReady (1) => non-ICC Contacts view is ready
+ * b) [listen times out] test must notify sync SIM lock error
+ * c&d) EReady (1) => ICC Views become Ready empty or with contacts only
+ */
+
+ // Contact only view should Ready
+ test(iViewEventQueue->ListenForEvent(10,event));
+
+ // Expecting EReady event
+ test.Printf(_L("Event received (%i)\n"), event.iEventType);
+ test(event.iEventType == TContactViewEvent::EReady);
+ readyCount++;
+
+ // there should be 1 Synch Change Notification request outstanding per phonebook
+ TInt notificationCount = syncChecker->TotalNotificationPendingCountL();
+ test(notificationCount == iPhbkList.Count());
+
+
+ // synchronise all phonebooks, with SIM card "access denied" condition
+ test(syncChecker->SynchroniseIccAllPhonebooksL(*iDb, KErrNone, KErrAccessDenied) == KErrNone);
+
+
+ // views with ICC entries should become ready now
+ while ((readyCount < 3) && iViewEventQueue->ListenForEvent(10,event))
+ {
+ // Expecting EReady events
+ switch (event.iEventType)
+ {
+ case TContactViewEvent::EItemAdded:
+ test.Printf(_L("Event received - EItemAdded\n"));
+ // ignore events from adding contacts
+ break;
+
+ case TContactViewEvent::EGroupChanged:
+ test.Printf(_L("Event received - EGroupChanged (group Id %i)\n"), event.iContactId);
+ // ignore events from adding contacts
+ break;
+
+ case TContactViewEvent::EReady:
+ test.Printf(_L("Event received - EReady\n"));
+ readyCount++;
+ break;
+
+ default:
+ test.Printf(_L("Unexpected event received (%i)\n"), event.iEventType);
+ test(0);
+ }
+ }
+
+
+ test(readyCount == 3);
+
+ // there should be 1 Synch Change Notification request outstanding per phonebook
+ notificationCount = syncChecker->TotalNotificationPendingCountL();
+ test(notificationCount == iPhbkList.Count());
+
+ // check number of entries in views (ICC locked)
+ VerifyNumberOfEntriesInEachViewL(ESyncIccLocked);
+
+ // Test Step 5. The PhoneBook Synch then indicates that the Cache is Valid.
+ test(syncChecker->SynchroniseIccAllPhonebooksL(*iDb, KErrNone, KErrNone) == KErrNone);
+ test.Printf(_L("PhoneBook Synch completed, cache now valid\n"));
+
+ // Test Step 6. The two ICC views are updated (re-sorted) with the ICC entries.
+
+ /* The 2 Views with ICC entries will each have 2 events:
+ * a) EUnavailable (0) => view is unavailable
+ * b) ESortOrderChanged (2) => view is Ready again
+ *
+ * For the 2 Views these can be interleaved
+ */
+ while ((unavailableCount < 2) || (sortOrderChangedCount < 2))
+ {
+ TBool eventReceived = iViewEventQueue->ListenForEvent(1,event);
+
+ if (eventReceived)
+ {
+ switch(event.iEventType)
+ {
+ case TContactViewEvent::EItemAdded:
+ test.Printf(_L("Event received - EItemAdded (Id %i)\n"), event.iContactId);
+ // ignore events from adding contacts
+ break;
+
+ case TContactViewEvent::EGroupChanged:
+ test.Printf(_L("Event received - EGroupChanged (group Id %i)\n"), event.iContactId);
+ // ignore events from adding contacts
+ break;
+
+ case TContactViewEvent::ESortOrderChanged:
+ test.Printf(_L("Event received - ESortOrderChanged\n"));
+ sortOrderChangedCount++;
+ test(sortOrderChangedCount <= unavailableCount);
+ break;
+
+ case TContactViewEvent::EUnavailable:
+ test.Printf(_L("Event received - EUnavailable\n"));
+ unavailableCount++;
+ test(unavailableCount <= 2);
+ break;
+
+ default:
+ test.Printf(_L("Unexpected event received (%i)\n"), event.iEventType);
+ test(EFalse);
+ break;
+ }
+ }
+ }
+
+ // there should be 1 Synch Change Notification request outstanding per phonebook
+ notificationCount = syncChecker->TotalNotificationPendingCountL();
+ test(notificationCount == iPhbkList.Count());
+
+ // check number of entries in views (ICC synchronised)
+ VerifyNumberOfEntriesInEachViewL(ESynchronised);
+
+ // Check the number of requests made to the plug-in
+ // Expecting 6 calls in total from PhbkSync Watcher
+ // (NotifySyncStateChange + IsSynchronised) * 3
+ //
+
+ // Test Step 7. Cleanup (deletes all entries)
+ // delete non-Icc entries
+ DeleteEntriesL(iNonIccContacts.Count());
+ // delete Icc entries
+ DeleteEntriesL(iIccContacts.Count(), ETrue);
+
+ // no entries left
+ test((iNonIccContacts.Count() == 0) && (iIccContacts.Count() == 0));
+
+ // Flush all other events
+ iViewEventQueue->Flush();
+ }
+
+
+/**
+ Test View notifications when Phonebook Synch finishes
+ Takes parameters to stimulate error conditions in the synchronisation
+
+ Method: Start synchronisation then creates 3 views for Contacts, ICC Entries and Mixed Contacts & ICC Entries
+ Count/check the View events.
+ */
+void CICCViewTest::SyncThenCreateViewCheckEventsL(TInt aSyncCompletionError, TInt aIsSyncError)
+ {
+ // Wait for local views to get ready
+ TInt readyCount(0);
+ TInt sortErrorCount(0);
+ TContactViewEvent event;
+
+ // synchronise all phonebooks
+ test(syncChecker->SynchroniseIccAllPhonebooksL(*iDb, aSyncCompletionError, aIsSyncError) == KErrNone);
+
+
+ // create the view to test
+ CreateViewsL();
+
+ // Contact only view should Ready
+ test(iViewEventQueue->ListenForEvent(10,event));
+
+ // Expecting EReady event
+ test.Printf(_L("Event received (%i)\n"), event.iEventType);
+ test(event.iEventType == TContactViewEvent::EReady);
+ readyCount++;
+
+ // there should be 1 Synch Change Notification request outstanding per phonebook
+ TInt notificationCount = syncChecker->TotalNotificationPendingCountL();
+ test(notificationCount == iPhbkList.Count());
+
+ // Phbk Watchers should be created when views were created - check number of plug-in calls
+ //test(syncChecker->SyncMethodCallCountL() == (1 + 2 * iPhbkList.Count())); Johan
+
+
+ // views with ICC entries should become ready now
+ while (((readyCount + sortErrorCount) < 3) && iViewEventQueue->ListenForEvent(10,event))
+ {
+ // Expecting EReady events
+ switch (event.iEventType)
+ {
+ case TContactViewEvent::EItemAdded:
+ test.Printf(_L("Event received - EItemAdded\n"));
+ // ignore events from adding contacts
+ break;
+
+ case TContactViewEvent::EGroupChanged:
+ test.Printf(_L("Event received - EGroupChanged (group Id %i)\n"), event.iContactId);
+ // ignore events from adding contacts
+ break;
+
+ case TContactViewEvent::EReady:
+ test.Printf(_L("Event received - EReady\n"));
+ readyCount++;
+ break;
+
+ case TContactViewEvent::ESortError:
+ test.Printf(_L("Event received - ESortError\n"));
+ if (aSyncCompletionError != KErrNone)
+ {
+ test(event.iInt == aSyncCompletionError);
+ }
+ else
+ {
+ test(event.iInt == aIsSyncError);
+ }
+ sortErrorCount++;
+ break;
+
+ default:
+ test.Printf(_L("Unexpected event received (%i)\n"), event.iEventType);
+ test(0);
+ }
+ }
+
+ // either received all events or timed out waiting
+ if (aSyncCompletionError == KErrNone && aIsSyncError == KErrNone)
+ {
+ // all 3 views should be ready
+ test(readyCount == 3);
+
+ // check number of entries in views (ICC is synchronised)
+ VerifyNumberOfEntriesInEachViewL(ESynchronised);
+ }
+ else
+ {
+ // ICC views should have had sort errors
+ test(sortErrorCount == 2);
+
+ // check number of entries in views (ICC is not synchronised)
+ VerifyNumberOfEntriesInEachViewL(ENotSynchronised);
+ }
+
+
+ // there should be 1 Synch Change Notification request outstanding per phonebook
+ notificationCount = syncChecker->TotalNotificationPendingCountL();
+ test(notificationCount == iPhbkList.Count());
+
+ // Check the number of requests made to the plug-in
+ const TInt methodCount = syncChecker->SyncMethodCallCountL();
+ if (aSyncCompletionError == KErrNone)
+ {
+ // There should be 1 call plus 2 per phonebook to the Phonebook Sync plug-in
+ // PhonebookList + N * (NotifySyncStateChange, IsSynchronised)
+ test(methodCount == 2 + (4 * iPhbkList.Count()));
+ }
+ else
+ {
+ // There should be 1 call plus 2 per phonebook to the Phonebook Sync plug-in
+ // PhonebookList + N * NotifySyncStateChange + N * 2 * (IsSynchronised, NotifySyncStateChange)
+ test(methodCount == 1 + (5 * iPhbkList.Count()));
+ }
+
+
+ // Flush all other events
+ iViewEventQueue->Flush();
+ }
+
+
+/**
+ Test Objective: Test Phonebook Synch for SIM card that starts Locked and becomes Unlocked.
+ - tests View events and number of contacts in views
+
+ Differs from test 4 in that the initial Phonebook Sync state (SIM locked) is indicated
+ before the views are created.
+
+ Method: Creates 3 views for Contacts, ICC Entries and Mixed Contacts & ICC Entries.
+ Simulated Phonebook Synch fails with ICC card locked, subsequently card becomes unlocked
+ and Phonebook Synch succeeds.
+
+ Test steps:
+ 1. PhoneBook Synch fails with an error due to SIM card (ICC) locked.
+ 2. Create Views and some non-ICC Contacts.
+ 2. Contacts only view becomes ready
+ 4. The two ICC views become available without ICC entries.
+ 5. The PhoneBook Synch then indicates that the Cache is Valid.
+ 6. The two ICC views are updated (re-sorted) with the ICC entries.
+ 7. Cleanup (deletes all entries)
+ */
+void CICCViewTest::CheckEventsForTestSevenL()
+ {
+ // Wait for local views to get ready
+ TContactViewEvent event;
+ TInt readyCount(0);
+ TInt unavailableCount(0);
+ TInt sortOrderChangedCount(0);
+
+ // Test step 1. synchronise all phonebooks, with SIM card "access denied" condition
+ test(syncChecker->SynchroniseIccAllPhonebooksL(*iDb, KErrNone, KErrAccessDenied) == KErrNone);
+
+
+ // Test Step 2. Create views and some non-ICC Contacts.
+ CreateViewsL();
+ test.Printf(_L("Creating 5 Contacts\n"));
+ CreateEntriesNoVerifyL(5);
+
+ // This While loop tests for steps:
+ // 2. Contacts only view becomes ready, and
+ // 3. The two ICC views become available without ICC entries.
+
+ /* Expected events:
+ * a) EReady (1) => non-ICC Contacts view is ready
+ * b&c) EReady (1) => ICC Views become Ready empty or with contacts only
+ */
+
+ // views with ICC entries should become ready now
+ while ((readyCount < 3) && iViewEventQueue->ListenForEvent(10,event))
+ {
+ // Expecting EReady events
+ switch (event.iEventType)
+ {
+ case TContactViewEvent::EItemAdded:
+ test.Printf(_L("Event received - EItemAdded\n"));
+ // ignore events from adding contacts
+ break;
+
+ case TContactViewEvent::EGroupChanged:
+ test.Printf(_L("Event received - EGroupChanged (group Id %i)\n"), event.iContactId);
+ // ignore events from adding contacts
+ break;
+
+ case TContactViewEvent::EReady:
+ test.Printf(_L("Event received - EReady\n"));
+ readyCount++;
+ break;
+
+ default:
+ test.Printf(_L("Unexpected event received (%i)\n"), event.iEventType);
+ test(0);
+ }
+ }
+
+ test(readyCount == 3);
+
+ // there should be 1 Synch Change Notification request outstanding per phonebook
+ TInt notificationCount = syncChecker->TotalNotificationPendingCountL();
+ test(notificationCount == iPhbkList.Count());
+
+ // check number of entries in views (ICC locked)
+ VerifyNumberOfEntriesInEachViewL(ESyncIccLocked);
+
+ // Test Step 5. The PhoneBook Synch then indicates that the Cache is Valid.
+ test(syncChecker->SynchroniseIccAllPhonebooksL(*iDb, KErrNone, KErrNone) == KErrNone);
+ test.Printf(_L("PhoneBook Synch completed, cache now valid\n"));
+
+ // Test Step 6. The two ICC views are updated (re-sorted) with the ICC entries.
+
+ /* The 2 Views with ICC entries will each have 2 events:
+ * a) EUnavailable (0) => view is unavailable
+ * b) ESortOrderChanged (2) => view is Ready again
+ *
+ * For the 2 Views these can be interleaved
+ */
+ while ((unavailableCount < 2) || (sortOrderChangedCount < 2))
+ {
+ TBool eventReceived = iViewEventQueue->ListenForEvent(1,event);
+
+ if (eventReceived)
+ {
+ switch(event.iEventType)
+ {
+ case TContactViewEvent::EItemAdded:
+ test.Printf(_L("Event received - EItemAdded (Id %i)\n"), event.iContactId);
+ // ignore events from adding contacts
+ break;
+
+ case TContactViewEvent::EGroupChanged:
+ test.Printf(_L("Event received - EGroupChanged (group Id %i)\n"), event.iContactId);
+ // ignore events from adding contacts
+ break;
+
+ case TContactViewEvent::ESortOrderChanged:
+ test.Printf(_L("Event received - ESortOrderChanged\n"));
+ sortOrderChangedCount++;
+ test(sortOrderChangedCount <= unavailableCount);
+ break;
+
+ case TContactViewEvent::EUnavailable:
+ test.Printf(_L("Event received - EUnavailable\n"));
+ unavailableCount++;
+ test(unavailableCount <= 2);
+ break;
+
+ default:
+ test.Printf(_L("Unexpected event received (%i)\n"), event.iEventType);
+ test(EFalse);
+ break;
+ }
+ }
+ }
+
+ // there should be 1 Synch Change Notification request outstanding per phonebook
+ notificationCount = syncChecker->TotalNotificationPendingCountL();
+ test(notificationCount == iPhbkList.Count());
+
+ // check number of entries in views (ICC synchronised)
+ VerifyNumberOfEntriesInEachViewL(ESynchronised);
+
+ // Check the number of requests made to the plug-in
+ // Expecting 6 calls in total from PhbkSync Watcher
+ // (NotifySyncStateChange + IsSynchronised) * 3
+ //
+ TInt methodCount = syncChecker->SyncMethodCallCountL();
+ // Number of expected calls to syncChecker->MethodCalledL()
+ test(methodCount = 6);
+
+ // Test Step 7. Cleanup (deletes all entries)
+ // delete non-Icc entries
+ DeleteEntriesL(iNonIccContacts.Count());
+ // delete Icc entries
+ DeleteEntriesL(iIccContacts.Count(), ETrue);
+
+ // no entries left
+ test((iNonIccContacts.Count() == 0) && (iIccContacts.Count() == 0));
+
+ // Flush all other events
+ iViewEventQueue->Flush();
+ }
+
+
+CICCViewTest::~CICCViewTest()
+ {
+ iIccContacts.Reset();
+ iIccContacts.Close();
+ iNonIccContacts.Reset();
+ iNonIccContacts.Close();
+ if (iContactsView)
+ iContactsView->Close(*iViewEventQueue);
+ if (iIccView)
+ iIccView->Close(*iViewEventQueue);
+ if (iContactsAndIccView)
+ iContactsAndIccView->Close(*iViewEventQueue);
+
+ delete iViewEventQueue;
+ iViewSortOrder.Close();
+ delete iEntry;
+ delete iTemplate;
+ delete iDb;
+ TRAP_IGNORE(CContactDatabase::DeleteDatabaseL(KTestDbName));
+ }
+
+void CICCViewTest::CreateEntriesL(TInt aNumberOfEntries, TBool aIsIccEntry)
+ {
+ iViewEventQueue->Flush();
+ for (TInt i=0; i<aNumberOfEntries; i++)
+ {
+ CreateEntryL(aIsIccEntry);
+ }
+
+ // wait for views to be updated
+ TContactViewEvent event;
+ test(iViewEventQueue->ListenForEvent(10,event));
+ test((event.iEventType == TContactViewEvent::EItemAdded) || (event.iEventType == TContactViewEvent::EGroupChanged));
+
+ // Eat away events
+ do{}
+ while (iViewEventQueue->ListenForEvent(1,event));
+
+ // Check views
+ VerifyNumberOfEntriesInEachViewL(ESynchronised);
+ }
+
+void CICCViewTest::CreateEntriesNoVerifyL(TInt aNumberOfEntries, TBool aIsIccEntry)
+ {
+ // add Contacts entries, but don't verify now
+ for (TInt i=0; i<aNumberOfEntries; i++)
+ {
+ if(aIsIccEntry)
+ {
+ test.Printf(_L(" Adding SIM contact - - -\n"));
+ }
+ CreateEntryL(aIsIccEntry);
+ }
+ }
+
+void CICCViewTest::CreateEntryL(TBool aIsIccEntry)
+ {
+ TBool iccEntry=EFalse;
+ if (aIsIccEntry)
+ {
+ if (iTemplate == NULL)
+ {
+ TContactItemId templateId = iDb->ICCTemplateIdL(iPhbkList[0]);
+ iTemplate = iDb->ReadContactL(templateId);
+ }
+
+ iEntry=CContactICCEntry::NewL(*iTemplate);
+ iccEntry=ETrue;
+ }
+ else
+ {
+ iEntry=CContactCard::NewL();
+ }
+
+ HBufC* buf=HBufC::NewLC(32);
+ TPtr bufPtr=buf->Des();
+ SetRandomAlphaString(bufPtr,16);
+
+ CContactItemFieldSet& fieldSet=iEntry->CardFields();
+ const TInt pos=fieldSet.Find(KUidContactFieldGivenName);
+ if (pos!=KErrNotFound)
+ fieldSet[pos].TextStorage()->SetTextL(bufPtr);
+
+ iDb->AddNewContactL(*iEntry);
+ if(iccEntry)
+ {
+ iIccContacts.Append(iEntry->Id());
+ }
+ else
+ {
+ iNonIccContacts.Append(iEntry->Id());
+ }
+ CleanupStack::PopAndDestroy(buf);
+
+ delete iEntry;
+ iEntry=NULL;
+ }
+
+void CICCViewTest::DeleteEntriesL(TInt aNumberOfEntries, TBool aIccEntry)
+ {
+ if(aIccEntry)
+ {
+ const TInt max = iIccContacts.Count();
+ if(aNumberOfEntries > max)
+ {
+ aNumberOfEntries = max;
+ }
+
+ for(TInt i=0; i<aNumberOfEntries; i++)
+ {
+ iDb->DeleteContactL(iIccContacts[0]);
+ iIccContacts.Remove(0);
+ }
+ }
+ else
+ {
+ const TInt max = iNonIccContacts.Count();
+ if(aNumberOfEntries > max)
+ {
+ aNumberOfEntries = max;
+ }
+
+ for(TInt i=0; i<aNumberOfEntries; i++)
+ {
+ iDb->DeleteContactL(iNonIccContacts[0]);
+ iNonIccContacts.Remove(0);
+ }
+ }
+
+ // Eat away events
+ TContactViewEvent event;
+ do{}
+ while (iViewEventQueue->ListenForEvent(1,event));
+
+ // Check views
+ VerifyNumberOfEntriesInEachViewL(ESynchronised);
+ }
+
+void CICCViewTest::VerifyNumberOfEntriesInEachViewL(TSyncStatus aSyncStatus)
+ {
+ // any sync status -> check non Icc View
+ TInt nonIcc = iContactsView->CountL();
+ // number items in view matches the number of contacts added?
+ test(nonIcc == iNonIccContacts.Count());
+
+
+ // should ICC views be ready?
+ if (aSyncStatus == ESynchronised || aSyncStatus == ESyncIccLocked)
+ {
+ TInt Icc=iIccView->CountL();
+ TInt both=iContactsAndIccView->CountL();
+
+ if (aSyncStatus == ESynchronised)
+ {
+ test(Icc == iInitialIccCount + iIccContacts.Count());
+ test(both == iInitialIccCount + iNonIccContacts.Count() + iIccContacts.Count());
+ }
+ else // ESyncIccLocked -> no sync of ICC entries
+ {
+ test(Icc == iIccContacts.Count());
+ test(both == iNonIccContacts.Count() + iIccContacts.Count());
+ }
+ }
+ }
+
+void CICCViewTest::SetRandomAlphaString(TDes& aBuf,TInt aLength)
+ {
+ aBuf.SetLength(aLength);
+
+ for (TInt ii=0;ii<aLength;++ii)
+ {
+ aBuf[ii]=RandomCharCode('A','z',' ');
+ }
+ }
+
+TText CICCViewTest::RandomCharCode(TText aLowerBound,TText aUpperBound,TText aException)
+ {
+ TText charCode=0;
+
+ do
+ {
+ charCode=RandomCharCode(aLowerBound,aUpperBound);
+ }
+ while (charCode==aException);
+
+ return charCode;
+ }
+
+TText CICCViewTest::RandomCharCode(TText aLowerBound,TText aUpperBound)
+ {
+ TText charCode=STATIC_CAST(TText,(Math::Rand(iRandSeed)%(aUpperBound-aLowerBound))+aLowerBound);
+ ASSERT(charCode>=aLowerBound && charCode<=aUpperBound);
+ return charCode;
+ }
+
+void CheckForPhbkSyncPluginL()
+ {
+ test.Next(_L("Check for PhbkSync test plug-in"));
+
+ RImplInfoPtrArray implInfoArray;
+ CleanupResetAndDestroyPushL(implInfoArray);
+ REComSession::ListImplementationsL(KUidEcomCntPhBkSyncInterface, implInfoArray);
+ //Find implementations of KUidEcomCntPhBkSyncInterface
+ TInt availCount = implInfoArray.Count();
+ TInt count;
+ for(count = 0; count < availCount; count++)
+ {
+ const TUid firstImplementationFound = implInfoArray[count]->ImplementationUid();
+ CImplementationInformation *info = implInfoArray[count];
+ test.Printf(_L("\n"));
+ test.Printf(_L("PhbkSync plugin #%i, Implementation UID 0x%08X version %i\n"),
+ count + 1, info->ImplementationUid(), info->Version());
+ test.Printf(_L("Plugin name = \"%S\"\n"), &(info->DisplayName()));
+ }
+
+ // is telephony's plug-in in the list?
+ for(count = 0; count < availCount; count++)
+ {
+ const TUid firstImplementationFound = implInfoArray[count]->ImplementationUid();
+ CImplementationInformation *info = implInfoArray[count];
+ if(info->DisplayName() == KTestPluginName)
+ {
+ test.Printf(_L("\n"));
+ test.Printf(_L("This test has now loaded the test plugin"));
+ test.Printf(_L("\n"));
+ availCount = 1;
+ break;
+ }
+
+ if(info->DisplayName() == KPluginName)
+ {
+ test.Printf(_L("\n"));
+ test.Printf(_L("This test only works with Contacts the test plugin and not the original phonebooksync plugin."));
+ test.Printf(_L("Depending on the build to removed the plugin in different ways:"));
+ test.Printf(_L("hardware - delete the line \"ECOM_PLUGIN(phbksyncplugin.dll,1020428C.rsc)\" from phbksync.iby"));
+ test.Printf(_L("winscw - delete phbksyncplugin.dll from %epocroot%/epoc32/release/winscw/udeb or similarly named directory"));
+ test.Printf(_L("\n"));
+ test(0); // stop
+ break;
+ }
+ }
+
+ // only continue test if there is exactly one plug-in present
+ test(availCount == 1);
+
+ CleanupStack::PopAndDestroy(&implInfoArray);
+
+ }
+
+
+void CICCViewTest::TestOneOrFiveL(TBool aCreateViewBeforeSync)
+ {
+ // Tests succesful Phonebook Synchronisation
+ if (aCreateViewBeforeSync)
+ {
+ CheckViewCreateAndSyncEventsL(KErrNone, KErrNone);
+
+
+ test.Next(_L("Test creation and deletion of ICC entries"));
+ // create some icc and non-icc entries
+ CreateEntriesL(5);
+ CreateEntriesL(4, ETrue);
+ CreateEntriesL(2);
+
+ // delete some icc and non-icc entries
+ DeleteEntriesL(3);
+ DeleteEntriesL(iIccContacts.Count(), ETrue);
+ DeleteEntriesL(iNonIccContacts.Count());
+ }
+ else
+ {
+ SyncThenCreateViewCheckEventsL(KErrNone, KErrNone);
+ }
+ }
+
+void CICCViewTest::TestTwoL()
+ {
+ // NB test only valid for creating view before Sync happens
+ // test condition when notification request completes with an error
+ CheckViewCreateAndSyncEventsL(KErrGeneral, KErrNone);
+ }
+
+void CICCViewTest::TestThreeOrSixL(TBool aCreateViewBeforeSync)
+ {
+ // test condition where notification completes okay, but IsSynchronisedL() leaves with an error
+ if (aCreateViewBeforeSync)
+ {
+ CheckViewCreateAndSyncEventsL(KErrNone, KErrGeneral);
+ }
+ else
+ {
+ SyncThenCreateViewCheckEventsL(KErrNone, KErrGeneral);
+ }
+ }
+
+void CICCViewTest::TestFourL()
+ {
+ CheckEventsForTestFourL();
+ }
+
+void CICCViewTest::TestSevenL()
+ {
+ CheckEventsForTestSevenL();
+ }
+
+void CICCViewTest::TestConcurrenceL()
+ {
+ test(syncChecker->SynchroniseIccAllPhonebooksL(*iDb, KErrNone, KErrNone) == KErrNone);
+
+ CContactRemoteView* iccRemoteView = CContactRemoteView::NewL(*iViewEventQueue, *iDb, iViewSortOrder, EICCEntriesOnly);
+
+ TContactViewEvent event;
+ test(iViewEventQueue->ListenForEvent(10,event));
+
+ // Expecting EReady event
+ test.Printf(_L("Event received (%i)\n"), event.iEventType);
+ test(event.iEventType == TContactViewEvent::EReady);
+
+ //Create and close another contact client session
+ CContactDatabase* newDb = CContactDatabase::OpenL(KTestDbName);
+ delete newDb;
+
+ //Close the view to see if there is concurrence resource conflication.
+ iccRemoteView->Close(*iViewEventQueue);
+
+ //delete all icc and non-icc entries
+ DeleteEntriesL(iIccContacts.Count(), ETrue);
+ }
+
+void RunTestOneL(const RArray<TUid> aPhonebookList)
+ {
+ test.Next(_L("Test view construction (create view before sync)"));
+
+ CICCViewTest* viewTest=CICCViewTest::NewLC(aPhonebookList);
+ viewTest->TestOneOrFiveL(ETrue);
+
+ CleanupStack::PopAndDestroy(viewTest);
+ }
+
+void RunTestTwoL(const RArray<TUid> aPhonebookList)
+ {
+ test.Next(_L("Test error handling: NotifySyncStateChange (create view before sync)"));
+
+ CICCViewTest* viewTest=CICCViewTest::NewLC(aPhonebookList);
+ viewTest->TestTwoL();
+ CleanupStack::PopAndDestroy(viewTest);
+ }
+
+void RunTestThreeL(const RArray<TUid> aPhonebookList)
+ {
+ test.Next(_L("Test error handling: IsICCSynchronisedL (create view before sync)"));
+
+ CICCViewTest* viewTest=CICCViewTest::NewLC(aPhonebookList);
+ viewTest->TestThreeOrSixL(ETrue);
+ CleanupStack::PopAndDestroy(viewTest);
+ }
+
+void RunTestFourL(const RArray<TUid> aPhonebookList)
+ {
+ test.Next(_L("Test error handling: SIM Locked and then Unlocked (create view before sync)"));
+
+ CICCViewTest* viewTest=CICCViewTest::NewLC(aPhonebookList);
+ viewTest->TestFourL();
+ CleanupStack::PopAndDestroy(viewTest);
+ }
+
+void RunTestFiveL(const RArray<TUid> aPhonebookList)
+ {
+ test.Next(_L("Test view construction (sync before view creation)"));
+
+ CICCViewTest* viewTest=CICCViewTest::NewLC(aPhonebookList);
+ viewTest->TestOneOrFiveL(EFalse);
+
+ CleanupStack::PopAndDestroy(viewTest);
+ }
+
+void RunTestSixL(const RArray<TUid> aPhonebookList)
+ {
+ test.Next(_L("Test error handling: IsICCSynchronisedL (sync before view creation)"));
+
+ CICCViewTest* viewTest=CICCViewTest::NewLC(aPhonebookList);
+ viewTest->TestThreeOrSixL(EFalse);
+ CleanupStack::PopAndDestroy(viewTest);
+ }
+
+void RunTestSevenL(const RArray<TUid> aPhonebookList)
+ {
+ test.Next(_L("Test error handling: SIM Locked and then Unlocked (sync before view creation)"));
+
+ CICCViewTest* viewTest=CICCViewTest::NewLC(aPhonebookList);
+ viewTest->TestSevenL();
+ CleanupStack::PopAndDestroy(viewTest);
+ }
+
+void RunConcurrenceTestL(const RArray<TUid> aPhonebookList)
+ {
+ test.Next(_L("Test error handling: SIM Locked and then Unlocked (sync before view creation)"));
+
+ CICCViewTest* viewTest = CICCViewTest::NewLC(aPhonebookList);
+ viewTest->TestConcurrenceL();
+
+ CleanupStack::PopAndDestroy(viewTest);
+ }
+
+/**
+
+@SYMTestCaseID PIM-T-ICCVIEW-0001
+
+*/
+
+void DoTestsL()
+ {
+ test.Start(KTestName);
+
+ CheckForPhbkSyncPluginL();
+
+ syncChecker = CContactSyncChecker::NewL();
+ syncChecker->ResetEverythingL();
+ //syncChecker->EnableVerboseLoggingL();
+
+ RArray<TUid> phbkList;
+ CleanupClosePushL(phbkList);
+
+ for(TInt loop = 0; loop < 3; ++loop)
+ {
+ switch (loop)
+ {
+ case 0:
+ phbkList.Reset();
+ phbkList.AppendL(KUidIccGlobalAdnPhonebook);
+ test.Next(_L("Test with GSM Global ADN phonebook"));
+ break;
+
+ case 1:
+ phbkList.Reset();
+ phbkList.AppendL(KUidUsimAppAdnPhonebook);
+ test.Next(_L("Test with USIM App ADN phonebook"));
+ break;
+
+ case 2:
+ phbkList.Reset();
+ phbkList.AppendL(KUidIccGlobalAdnPhonebook);
+ phbkList.AppendL(KUidUsimAppAdnPhonebook);
+ test.Next(_L("Test with GSM Global and USIM App ADN phonebooks"));
+ break;
+
+ default:
+ test(0);
+ }
+
+ test.Start(_L("Phonebook Sync tests"));
+ // all tests work with any number of phonebooks
+ RunTestOneL(phbkList);
+ RunTestTwoL(phbkList);
+ RunTestThreeL(phbkList);
+ RunTestFourL(phbkList);
+
+ RunTestFiveL(phbkList);
+ RunTestSixL(phbkList);
+ RunTestSevenL(phbkList);
+
+ test.End();
+ }
+
+#ifdef CNTTEST_ICCREMOTEVIEW
+ //The concurrence test is marked off because currently the cntsyncchecker has
+ //problem in remoteview which will block the contact server. -- See INC112963
+ test.Next(_L("Phonebook Sync Concurrence Test"));
+ phbkList.Reset();
+ phbkList.AppendL(KUidUsimAppAdnPhonebook);
+ RunConcurrenceTestL(phbkList);
+#endif //CNTTEST_ICCREMOTEVIEW
+
+ test.End();
+ test.Close();
+
+ CleanupStack::PopAndDestroy(); // phbkList
+
+ delete syncChecker;
+ syncChecker = NULL;
+ }
+
+GLDEF_C TInt E32Main()
+ {
+ RProcess().SetPriority(EPriorityBackground);
+ 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());
+
+ if (syncChecker)
+ {
+ delete syncChecker;
+ syncChecker = NULL;
+ }
+
+ test(err == KErrNone);
+
+ // Cleanup
+ delete activeScheduler;
+ delete cleanupStack;
+ return err;
+ }