--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mobilemessaging/smsmtm/test/src/t_smsdetails.cpp Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,698 @@
+// Copyright (c) 2004-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 "t_smsdetails.h"
+
+#include <e32test.h>
+#include <smutset.h>
+#include <smuthdr.h>
+#include <txtrich.h>
+#include "smstestutils.h"
+#include <msvuids.h>
+#include <smsuaddr.h>
+#include <csmsaccount.h>
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <tmsvsmsentry.h>
+#endif
+
+_LIT(KFailed,"Failed to complete tests.");
+_LIT(KRecipientOk, "+447747065441"); // has to be the number of SIM in the data blok
+_LIT(KMessageData, "This is a simple text message");
+
+_LIT(KFirstName, "Joe");
+_LIT(KLastName, "Bloggs");
+_LIT(KContactInfo, "Joe Bloggs");
+
+_LIT(KTestReceiveDetails_1, "Test receive details - number not in contacts database.");
+_LIT(KTestReceiveDetails_2, "Test receive details - number in contacts database.");
+_LIT(KTestReceiveDetails_3, "Test receive details - number duplicated in contacts database.");
+
+#if defined (__WINS__)
+_LIT(KPddName,"ECDRV");
+_LIT(KLddName,"ECOMM");
+#else //__WINS__
+_LIT(KPddSirName,"ESIR");
+_LIT(KPddUartName,"ECUART4");
+_LIT(KLddName,"ECOMM");
+#endif //__WINS__
+
+RTest test(_L("T_SmsDetails Test Harness"));
+
+const TTimeIntervalMicroSeconds32 KWaitForWatchersToStart = 20000000;
+const TTimeIntervalMicroSeconds32 KWaitForWatchersToStartDisplayInterval = 5000000;
+
+LOCAL_C void DoTestsL()
+ {
+#if defined (__WINS__)
+ User::LoadPhysicalDevice(KPddName);
+ User::LoadLogicalDevice(KLddName);
+#else //__WINS__
+ User::LoadPhysicalDevice(KPddSirName);
+ User::LoadPhysicalDevice(KPddUartName);
+ User::LoadLogicalDevice(KLddName);
+#endif //__WINS__
+
+ TInt r = StartC32();
+ if( (r != KErrNone) && (r != KErrAlreadyExists) )
+ test.Printf(_L("Failed to start C32 %d\n"), r);
+
+ // Create and install the active scheduler
+ CActiveScheduler* scheduler= new (ELeave) CActiveScheduler();
+ CleanupStack::PushL(scheduler);
+ CActiveScheduler::Install(scheduler);
+
+ // Create the test engine
+ CTestEngine* testEngine = CTestEngine::NewL();
+ CleanupStack::PushL(testEngine);
+
+ // Do tests...
+ testEngine->DoTestsL();
+
+ CleanupStack::PopAndDestroy(2, scheduler);
+ }
+
+GLDEF_C TInt E32Main()
+ {
+ __UHEAP_MARK;
+ CTrapCleanup* tc=CTrapCleanup::New();
+ TRAPD(err,DoTestsL());
+ if (err!=KErrNone)
+ User::Panic(KFailed, err);
+ delete tc;
+ test.Close();
+ __UHEAP_MARKEND;
+ return KErrNone;
+ }
+
+/*
+ * CTestEngine
+ */
+
+CTestEngine* CTestEngine::NewL()
+ {
+ CTestEngine* self = new (ELeave) CTestEngine();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CTestEngine::~CTestEngine()
+ {
+ delete iTestUtils;
+ delete iWatchers;
+
+ iSocket.Close();
+ iSocketServ.Close();
+ }
+
+CTestEngine::CTestEngine()
+: CBase()
+ {
+ }
+
+void CTestEngine::DoTestsL()
+ {
+ CTestDetailsBase* testCase = NULL;
+
+ testCase = CTestReceiveDetails_1::NewL(*iTestUtils, *this);
+ RunTestCaseL(*testCase);
+
+ testCase = CTestReceiveDetails_2::NewL(*iTestUtils, *this);
+ RunTestCaseL(*testCase);
+
+ testCase = CTestReceiveDetails_3::NewL(*iTestUtils, *this);
+ RunTestCaseL(*testCase);
+
+ if( iTestFailCount > 0 )
+ iTestUtils->Printf(_L("Test Complete -> %d Failures\n"), iTestFailCount);
+ else
+ iTestUtils->Printf(_L("Test Complete -> Passed\n"));
+ }
+
+void CTestEngine::RunTestCaseL(CTestDetailsBase& aTestCase)
+ {
+ CleanupStack::PushL(&aTestCase);
+ aTestCase.Start();
+ CActiveScheduler::Start();
+ CleanupStack::PopAndDestroy(&aTestCase);
+ }
+
+void CTestEngine::ConstructL()
+ {
+ // This should create the SMS service, including the service settings.
+ iTestUtils = CSmsTestUtils::NewL(test);
+
+ // Remove the contacts database file
+ iTestUtils->DeleteContactsFileL();
+
+ // Notify the system agent that the phone is on.
+ iTestUtils->NotifySaPhoneOnL();
+
+ // Tell the tests utils to log to file
+ iTestUtils->SetLogToFile();
+
+ // Restore the service settings.
+ iTestUtils->SetEntryL(iTestUtils->iSmsServiceId);
+ CSmsAccount* account = CSmsAccount::NewLC();
+ account->LoadSettingsL(*iTestUtils->iServiceSettings);
+
+ // Remove the default service centres from the service settings
+ TInt count = iTestUtils->iServiceSettings->ServiceCenterCount();
+ while( count-- )
+ {
+ iTestUtils->iServiceSettings->RemoveServiceCenter(count);
+ }
+
+ // Add the Vodafone service centre - store the settings.
+ iTestUtils->iServiceSettings->AddServiceCenterL(_L("Vodafone"), _L("+447785016005"));
+
+ // Set delivery options - do matching and make reports visible.
+ iTestUtils->iServiceSettings->SetDeliveryReport(ETrue);
+ iTestUtils->iServiceSettings->SetStatusReportHandling(CSmsSettings::EMoveReportToInboxVisibleAndMatch);
+
+ account->SaveSettingsL(*iTestUtils->iServiceSettings);
+ CleanupStack::PopAndDestroy(account);
+
+ // Create a session with the SMS stack - note order of the next few things
+ // is important.
+ User::LeaveIfError(iSocketServ.Connect());
+ TProtocolDesc protoinfo;
+ TProtocolName protocolname(KSmsDatagram);
+ User::LeaveIfError(iSocketServ.FindProtocol(protocolname,protoinfo));
+ User::LeaveIfError(iSocket.Open(iSocketServ,protoinfo.iAddrFamily,protoinfo.iSockType,protoinfo.iProtocol));
+
+ TSmsAddr smsaddr;
+ smsaddr.SetSmsAddrFamily(ESmsAddrSendOnly);
+ User::LeaveIfError(iSocket.Bind(smsaddr));
+
+ // Initialise phone...
+ iTestUtils->WaitForInitializeL();
+
+ // Start watchers...
+ StartWatcherL();
+ }
+
+TBool CTestEngine::WatchersAlreadyRunningL()
+ {
+ RSocketServ server;
+ RSocket socket;
+
+ User::LeaveIfError(server.Connect());
+ CleanupClosePushL(server);
+
+ // test if it's there...
+ TProtocolDesc protoInfo;
+ TProtocolName protocolname;
+ protocolname.Copy(KSmsDatagram);
+ User::LeaveIfError(server.FindProtocol(protocolname,protoInfo));
+
+ User::LeaveIfError(socket.Open(server,
+ protoInfo.iAddrFamily,
+ protoInfo.iSockType,
+ protoInfo.iProtocol));
+ CleanupClosePushL(socket);
+
+ TSmsAddr addr;
+ addr.SetSmsAddrFamily(ESmsAddrRecvAny);
+ TInt err = socket.Bind(addr);
+
+ CleanupStack::Pop(2, &server);
+ socket.CancelAll();
+ socket.Close();
+ server.Close();
+ return (err == KErrAlreadyExists);
+ }
+
+void CTestEngine::StartWatcherL()
+ {
+ iTestUtils->Printf(_L("Start the Watcher"));
+
+ if( WatchersAlreadyRunningL() )
+ {
+ iTestUtils->Printf(_L("Watchers are already running\n"));
+ return;
+ }
+
+ iWatchers = CTestUtilsWatcherStarter::NewL();
+
+ TTimeIntervalMicroSeconds32 wait = KWaitForWatchersToStart;
+ TBool started = EFalse;
+ while( !started && wait.Int() > 0 )
+ {
+ iTestUtils->Printf(_L("Waiting %d secs for watchers to start...\n"), wait.Int() / 1000000);
+ wait = wait.Int() - KWaitForWatchersToStartDisplayInterval.Int();
+ User::After(KWaitForWatchersToStartDisplayInterval);
+ started = WatchersAlreadyRunningL();
+ }
+
+ if( !WatchersAlreadyRunningL() )
+ {
+ iTestUtils->Printf(_L("WARNING: NBS Watcher has not started yet\n"));
+ }
+ }
+
+// methods from MTestObserver
+
+void CTestEngine::TestFailed()
+ {
+ iTestUtils->Printf(_L("!!Test Failed\n"));
+ ++iTestFailCount;
+ CActiveScheduler::Stop();
+ }
+
+void CTestEngine::TestPassed()
+ {
+ iTestUtils->Printf(_L("!!Test Complete\n"));
+ CActiveScheduler::Stop();
+ }
+
+/*
+ * CTestDetailsBase
+ */
+
+CTestDetailsBase::~CTestDetailsBase()
+ {
+ Cancel();
+
+ delete iEntryForObserver;
+ delete iOperation;
+ }
+
+void CTestDetailsBase::Start()
+ {
+ iTestUtils.Printf(_L("Starting %S\n"), &TestName());
+ iState = EClearFolders;
+ CompleteSelf();
+ }
+
+CTestDetailsBase::CTestDetailsBase(CSmsTestUtils& aTestUtils, MTestObserver& aObserver)
+: CActive(CActive::EPriorityStandard), iTestUtils(aTestUtils), iObserver(aObserver)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+void CTestDetailsBase::ConstructL()
+ {
+ iEntryForObserver = Session().GetEntryL(KMsvGlobalInBoxIndexEntryId);
+ }
+
+void CTestDetailsBase::CompleteSelf()
+ {
+ TRequestStatus* pStat = &iStatus;
+ User::RequestComplete(pStat, KErrNone);
+ SetActive();
+ }
+
+CMsvSession& CTestDetailsBase::Session()
+ {
+ return *iTestUtils.iMsvSession;
+ }
+
+CMsvEntry& CTestDetailsBase::MsvEntry()
+ {
+ return *iTestUtils.iMsvEntry;
+ }
+
+CSmsClientMtm& CTestDetailsBase::Client()
+ {
+ return *iTestUtils.iSmsClientMtm;
+ }
+
+CSmsSettings& CTestDetailsBase::ServiceSettings()
+ {
+ return *iTestUtils.iServiceSettings;
+ }
+
+void CTestDetailsBase::Test(TBool aTest)
+ {
+ if( !aTest )
+ iObserver.TestFailed();
+ }
+
+void CTestDetailsBase::ClearFoldersL()
+ {
+ iTestUtils.DeleteSmsMessagesL(KMsvGlobalOutBoxIndexEntryId);
+ iTestUtils.DeleteSmsMessagesL(KMsvGlobalInBoxIndexEntryId);
+ iTestUtils.DeleteSmsMessagesL(KMsvSentEntryId);
+ }
+
+void CTestDetailsBase::CreateMessageL()
+ {
+ iTestUtils.Printf(_L("Creating message...\n"));
+
+ TMsvEntry entry;
+ entry.SetVisible(ETrue);
+ entry.SetInPreparation(ETrue);
+ entry.iServiceId = iTestUtils.iSmsServiceId;
+ entry.iType = KUidMsvMessageEntry;
+ entry.iMtm = KUidMsgTypeSMS;
+ entry.iDate.HomeTime();
+ entry.iSize = 0;
+ entry.iDescription.Set(KNullDesC);
+ entry.iDetails.Set(KNullDesC);
+
+ // Check send options...
+ TUint sendState = KMsvSendStateWaiting;
+ switch( ServiceSettings().Delivery() )
+ {
+ case ESmsDeliveryScheduled:
+ sendState = KMsvSendStateScheduled;
+ break;
+ case ESmsDeliveryUponRequest:
+ sendState = KMsvSendStateUponRequest;
+ break;
+ default:
+ sendState = KMsvSendStateWaiting;
+ break;
+ }
+ entry.SetSendingState(sendState);
+
+ // Create the SMS header object...
+ CSmsHeader* header = CSmsHeader::NewL(CSmsPDU::ESmsSubmit, *iTestUtils.iRichText);
+ CleanupStack::PushL(header);
+
+ // Set the body text...
+ iTestUtils.iRichText->Reset();
+ iTestUtils.iRichText->InsertL(0, KMessageData);
+
+ // Copy the message settings...
+ header->SetSmsSettingsL(ServiceSettings());
+
+ // Set the service centre
+ TInt defaultIndex = ServiceSettings().DefaultServiceCenter();
+ header->SetServiceCenterAddressL(ServiceSettings().GetServiceCenter(defaultIndex).Address());
+
+ // Set recipient - ask derived class
+ SetRecipientsL(*header);
+
+ // Update entry description and details...
+ CArrayPtrFlat<CSmsNumber>& recipient = header->Recipients();
+ entry.iDetails.Set(recipient[0]->Address());
+ entry.iDescription.Set(iTestUtils.iRichText->Read(0, ServiceSettings().DescriptionLength()));
+ entry.SetInPreparation(EFalse);
+
+ // Create the entry - set context to the global outbox.
+ MsvEntry().SetEntryL(KMsvGlobalOutBoxIndexEntryId);
+ MsvEntry().CreateL(entry);
+
+ // Create new store and save header information
+ MsvEntry().SetEntryL(entry.Id());
+ CMsvStore* store = MsvEntry().EditStoreL();
+ CleanupStack::PushL(store);
+ header->StoreL(*store);
+ store->StoreBodyTextL(*iTestUtils.iRichText);
+ store->CommitL();
+ CleanupStack::PopAndDestroy(2, header);
+
+ iMessageId = entry.Id();
+ }
+
+void CTestDetailsBase::SetRecipientsL(CSmsHeader& aHeader)
+ {
+ CSmsNumber* rcpt0 = CSmsNumber::NewL();
+ CleanupStack::PushL(rcpt0);
+ rcpt0->SetAddressL(KRecipientOk);
+ aHeader.Recipients().AppendL(rcpt0);
+ CleanupStack::Pop(rcpt0);
+ }
+
+void CTestDetailsBase::SendMessageL()
+ {
+ iTestUtils.Printf(_L("Sending message %d\n"), iMessageId);
+
+ delete iOperation;
+ iOperation = NULL;
+
+ CMsvEntrySelection* sel = new (ELeave) CMsvEntrySelection();
+ CleanupStack::PushL(sel);
+ sel->AppendL(iMessageId);
+
+ iTestUtils.DisplayMessageL(iMessageId);
+
+ MsvEntry().SetEntryL(KMsvGlobalOutBoxIndexEntryId);
+ iOperation = MsvEntry().CopyL(*sel, iTestUtils.iSmsServiceId, iStatus);
+ CleanupStack::PopAndDestroy(sel);
+
+ SetActive();
+ }
+
+void CTestDetailsBase::ChangeServiceSettingsL()
+ {
+ // Restore the service settings.
+ iTestUtils.SetEntryL(iTestUtils.iSmsServiceId);
+ CSmsAccount* account = CSmsAccount::NewLC();
+ account->LoadSettingsL(*iTestUtils.iServiceSettings);
+
+ // Set the service settings
+ iTestUtils.iServiceSettings->SetValidityPeriod(TTimeIntervalMinutes(5));
+ iTestUtils.iServiceSettings->SetDeliveryReport(ETrue);
+ iTestUtils.iServiceSettings->SetStatusReportHandling(CSmsSettings::EMoveReportToInboxVisibleAndMatch);
+
+ // Store the new service settings
+ account->SaveSettingsL(*iTestUtils.iServiceSettings);
+ CleanupStack::PopAndDestroy(account);
+ }
+
+// methods from CActive
+
+void CTestDetailsBase::RunL()
+ {
+ User::LeaveIfError(iStatus.Int());
+
+ switch( iState )
+ {
+ case EClearFolders:
+ {
+ ClearFoldersL();
+ iState = EChangeServiceSettings;
+ CompleteSelf();
+ } break;
+ case EChangeServiceSettings:
+ {
+ ChangeServiceSettingsL();
+ iState = ECreateMessage;
+ CompleteSelf();
+ } break;
+ case ECreateMessage:
+ {
+ CreateMessageL();
+ iState = ESendMessage;
+ CompleteSelf();
+ } break;
+ case ESendMessage:
+ {
+ SendMessageL();
+ iState = EMessageSent;
+ } break;
+ case EMessageSent:
+ {
+ // Observer the in-box.
+ iEntryForObserver->SetEntryL(KMsvGlobalInBoxIndexEntryId);
+ iEntryForObserver->AddObserverL(*this);
+
+ iState = EPendingReceivedMessage;
+ } break;
+ case EPendingReceivedMessage:
+ {
+ // End the test...
+ iObserver.TestPassed();
+ } break;
+ default:
+ User::Invariant();
+ break;
+ }
+ }
+
+void CTestDetailsBase::DoCancel()
+ {
+ }
+
+TInt CTestDetailsBase::RunError(TInt /*aError*/)
+ {
+ return KErrNone;
+ }
+
+// methods from MMsvEntryObserver
+
+void CTestDetailsBase::HandleEntryEventL(TMsvEntryEvent aEvent, TAny* aArg1, TAny* /*aArg2*/, TAny* /*aArg3*/)
+ {
+ __ASSERT_DEBUG( iState == EPendingReceivedMessage, User::Invariant() );
+
+ if( aEvent == EMsvNewChildren )
+ {
+ iTestUtils.Printf(_L("Message received in in-box...\n"));
+
+ CMsvEntrySelection* sel = (CMsvEntrySelection*)(aArg1);
+
+ for( TInt ii=0; ii < sel->Count(); ++ii )
+ {
+ CheckReceivedMessageL(sel->At(ii));
+ }
+
+ // Test should be over - complete-self.
+ CompleteSelf();
+ }
+ }
+
+/*
+ * CTestReceiveDetails_1
+ */
+
+CTestReceiveDetails_1* CTestReceiveDetails_1::NewL(CSmsTestUtils& aTestUtils, MTestObserver& aObserver)
+ {
+ CTestReceiveDetails_1* self = new (ELeave) CTestReceiveDetails_1(aTestUtils, aObserver);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CTestReceiveDetails_1::~CTestReceiveDetails_1()
+ {
+ }
+
+CTestReceiveDetails_1::CTestReceiveDetails_1(CSmsTestUtils& aTestUtils, MTestObserver& aObserver)
+: CTestDetailsBase(aTestUtils, aObserver)
+ {
+ }
+
+// methods from CTestSendBase
+
+void CTestReceiveDetails_1::CheckReceivedMessageL(TMsvId aMessageId)
+ {
+ iTestUtils.Printf(_L("Checking received message %d has correct details\n"), aMessageId);
+
+ // Need to see that the details contains a telephone number
+ MsvEntry().SetEntryL(KMsvGlobalInBoxIndexEntryId);
+ MsvEntry().SetEntryL(aMessageId);
+ TMsvSmsEntry entry = MsvEntry().Entry();
+
+ // Recipient 2 delivered to first...
+ iTestUtils.Printf(_L("->Details info is %S - should be %S\n"), &entry.iDetails, &KRecipientOk());
+ Test(entry.iDetails.CompareF(KRecipientOk()) == 0);
+ }
+
+const TDesC& CTestReceiveDetails_1::TestName()
+ {
+ return KTestReceiveDetails_1();
+ }
+
+/*
+ * CTestReceiveDetails_2
+ */
+
+CTestReceiveDetails_2* CTestReceiveDetails_2::NewL(CSmsTestUtils& aTestUtils, MTestObserver& aObserver)
+ {
+ CTestReceiveDetails_2* self = new (ELeave) CTestReceiveDetails_2(aTestUtils, aObserver);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CTestReceiveDetails_2::~CTestReceiveDetails_2()
+ {
+ }
+
+CTestReceiveDetails_2::CTestReceiveDetails_2(CSmsTestUtils& aTestUtils, MTestObserver& aObserver)
+: CTestDetailsBase(aTestUtils, aObserver)
+ {
+ }
+
+void CTestReceiveDetails_2::ConstructL()
+ {
+ CTestDetailsBase::ConstructL();
+
+ // Add contact to database...
+ TContactItemId contId = iTestUtils.CreateContactL(KFirstName, KLastName, KRecipientOk, KNullDesC);
+ if( contId == KNullContactId )
+ User::Leave(KErrCorrupt);
+ }
+
+// methods from CTestSendBase
+
+void CTestReceiveDetails_2::CheckReceivedMessageL(TMsvId aMessageId)
+ {
+ iTestUtils.Printf(_L("Checking received message %d has correct details\n"), aMessageId);
+
+ // Need to see that the details contains a telephone number
+ MsvEntry().SetEntryL(KMsvGlobalInBoxIndexEntryId);
+ MsvEntry().SetEntryL(aMessageId);
+ TMsvSmsEntry entry = MsvEntry().Entry();
+
+ // Recipient 2 delivered to first...
+ iTestUtils.Printf(_L("->Details info is %S - should be %S\n"), &entry.iDetails, &KContactInfo());
+ Test(entry.iDetails.CompareF(KContactInfo()) == 0);
+ }
+
+const TDesC& CTestReceiveDetails_2::TestName()
+ {
+ return KTestReceiveDetails_2();
+ }
+
+/*
+ * CTestReceiveDetails_3
+ */
+
+CTestReceiveDetails_3* CTestReceiveDetails_3::NewL(CSmsTestUtils& aTestUtils, MTestObserver& aObserver)
+ {
+ CTestReceiveDetails_3* self = new (ELeave) CTestReceiveDetails_3(aTestUtils, aObserver);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CTestReceiveDetails_3::~CTestReceiveDetails_3()
+ {
+ }
+
+CTestReceiveDetails_3::CTestReceiveDetails_3(CSmsTestUtils& aTestUtils, MTestObserver& aObserver)
+: CTestDetailsBase(aTestUtils, aObserver)
+ {
+ }
+
+void CTestReceiveDetails_3::ConstructL()
+ {
+ CTestDetailsBase::ConstructL();
+
+ // Add contact to database - this is a duplicate...
+ TContactItemId contId = iTestUtils.CreateContactL(KFirstName, KLastName, KRecipientOk, KNullDesC);
+ if( contId == KNullContactId )
+ User::Leave(KErrCorrupt);
+ }
+
+// methods from CTestSendBase
+
+void CTestReceiveDetails_3::CheckReceivedMessageL(TMsvId aMessageId)
+ {
+ iTestUtils.Printf(_L("Checking received message %d has correct details\n"), aMessageId);
+
+ // Need to see that the details contains a telephone number
+ MsvEntry().SetEntryL(KMsvGlobalInBoxIndexEntryId);
+ MsvEntry().SetEntryL(aMessageId);
+ TMsvSmsEntry entry = MsvEntry().Entry();
+
+ // Recipient 2 delivered to first...
+ iTestUtils.Printf(_L("->Details info is %S - should be %S\n"), &entry.iDetails, &KRecipientOk());
+ Test(entry.iDetails.CompareF(KRecipientOk()) == 0);
+ }
+
+const TDesC& CTestReceiveDetails_3::TestName()
+ {
+ return KTestReceiveDetails_3();
+ }