/*
* 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>
#include "t_utils.h"
#include "cntsyncchecker.h"
#include "ccontactvieweventqueue.h"
#include "ccontactdbeventqueue.h"
#include <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;
}