--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingfw/msgtestfw/TestActions/Email/Pop3/src/CMtfTestActionVerifyReplyToAddress.cpp Mon Jan 18 20:36:02 2010 +0200
@@ -0,0 +1,411 @@
+// Copyright (c) 2006-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:
+// __ACTION_INFO_BEGIN__
+// [Action Name]
+// VerifyReplyToAddress
+// [Action Parameters]
+// 0) CMsvSession& session <input> :Reference to the session.
+// 1) CMsvEntrySelection& SentMailSelection <input> : Reference to the sent mail selection.
+// 2) CMsvEntrySelection& RecvMailSelection <input> : Reference to the received mail selection.
+// 3) TInt Number of mails under test.
+// 4) HBufC& Full Epoc32 file path of sample email txt file used.
+// 5) TInt Whether the sample email contains a Reply-To address field or not? (1 = ETrue, 0 = EFalse)
+// [Action Description]
+// Implements the action to compare the Reply-To address set in header of email from txt file to
+// that of the email actual sent as stored in the Message store as a TMsvEntry object.
+// [APIs Used]
+// __ACTION_INFO_END__
+//
+//
+
+/**
+ @file CMtfTestActionVerifyReplyToAddress.cpp
+*/
+
+#include <e32std.h>
+#include <txtrich.h>
+#include <mtclreg.h>
+#include <imcm.rsg>
+
+#include <msvstore.h>
+#include "CMtfTestActionVerifyReplyToAddress.h"
+#include <cemailaccounts.h>
+#include <iapprefs.h>
+#include "CMtfTestActionUtilsPopScripts.h"
+
+#include "CMtfTestActionUtils.h"
+#include "CMtfTestCase.h"
+#include "CMtfTestActionParameters.h"
+#include "MtfTestActionUtilsUser.h"
+#include "TMtfTestParameterType.h"
+#include "CPop3MailInfo.h"
+
+// Expected Reply-To field to be used in sample emails
+_LIT8(KReplyToField, "Reply-To: matthewf@msexchange2k.closedtest.intra\r\n");
+
+_LIT(KSettingsFile, "c:\\msgtest\\TestFramework\\Configurations\\EmailSettings\\Pop3Tests-lon-cn-exchng2k.txt");
+
+#ifdef _UNICODE
+ _LIT(KSmtpEmailAddressAndAliasFmtStr,"\"%S\" <%S>");
+#else
+ _LIT8(KSmtpEmailAddressAndAliasFmtStr,"\"%S\" <%S>");
+#endif
+
+/**
+ Function : NewL
+ Description : Standard symbian 2 phase constructor
+ @internalTechnology
+ @param aMtfTestCase - CMtfTestCase test case reference for base class constructor
+ @param aActionParameters - pointer to the parameters for this test action
+ @return A CMtfTestAction pointer to the newly created CMtfTestActionVerifyReplyToAddress object
+ @precondition none
+ @postcondition none
+*/
+CMtfTestAction* CMtfTestActionVerifyReplyToAddress::NewL(CMtfTestCase& aTestCase,CMtfTestActionParameters* aActionParameters)
+ {
+ CMtfTestActionVerifyReplyToAddress* self = new (ELeave) CMtfTestActionVerifyReplyToAddress(aTestCase);
+ CleanupStack::PushL(self);
+ self->ConstructL(aActionParameters);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/**
+ Function : CMtfTestActionVerifyReplyToAddress constructor
+ Description : Private constructor - must not leave
+ @internalTechnology
+ @param aTestCase - CMtfTestCase reference for the base class constructor
+ @return N/A
+ @precondition none
+ @postcondition none
+*/
+CMtfTestActionVerifyReplyToAddress::CMtfTestActionVerifyReplyToAddress(CMtfTestCase& aTestCase)
+: CMtfSynchronousTestAction(aTestCase), iSession(NULL), iSentSelectionList(NULL), iInboxSelectionList(NULL)
+ {
+ }
+
+/**
+ Function : CMtfTestActionVerifyReplyToAddress destructor
+ Description : Destructor
+ @internalTechnology
+ @param N/A
+ @return N/A
+ @precondition none
+ @postcondition none
+*/
+CMtfTestActionVerifyReplyToAddress::~CMtfTestActionVerifyReplyToAddress()
+ {
+ }
+
+/**
+ Function : LoadParametersL
+ Description : Loads the test action parameters
+ @internalTechnology
+ @param none
+ @return ETrue if parameters loaded Efalse on failure
+ @precondition none
+ @postcondition Upon failure TestCase status is EFail
+*/
+TBool CMtfTestActionVerifyReplyToAddress::LoadParametersL()
+ {
+ iSession = ObtainParameterReferenceL<CMsvSession> (TestCase(),ActionParameters().Parameter(0));
+ if(! iSession)
+ {
+ TestCase().ERR_PRINTF1(_L("Invalid session object"));
+ TestCase().SetTestStepResult(EFail);
+ return EFalse;
+ }
+ iSentSelectionList = ObtainParameterReferenceL<CMsvEntrySelection> (TestCase(), ActionParameters().Parameter(1));
+ if(! iSentSelectionList)
+ {
+ TestCase().ERR_PRINTF1(_L("Invalid sentSelectionList"));
+ TestCase().SetTestStepResult(EFail);
+ return EFalse;
+ }
+ iInboxSelectionList = ObtainParameterReferenceL<CMsvEntrySelection> (TestCase(), ActionParameters().Parameter(2));
+ if(! iInboxSelectionList)
+ {
+ TestCase().ERR_PRINTF1(_L("Invalid inboxSelectionList"));
+ TestCase().SetTestStepResult(EFail);
+ return EFalse;
+ }
+
+ if(iInboxSelectionList->Count() != iSentSelectionList->Count())
+ {
+ TestCase().ERR_PRINTF3(_L("iInboxSelectionList->Count(%d) != iSentSelectionList->Count(%d)"),
+ iInboxSelectionList->Count(), iSentSelectionList->Count() );
+ TestCase().SetTestStepResult(EFail);
+ return EFalse;
+ }
+
+ TInt numTests = ObtainValueParameterL<TInt> (TestCase(),ActionParameters().Parameter(3));
+ if(numTests != iInboxSelectionList->Count())
+ {
+ TestCase().ERR_PRINTF2(_L("NumTests != iInboxSelectionList->Count(%d)"), iInboxSelectionList->Count());
+ TestCase().SetTestStepResult(EFail);
+ return EFalse;
+ }
+
+ iEmailFilePath = ObtainParameterReferenceL<HBufC> (TestCase(),ActionParameters().Parameter(4));
+ TPtr ptrEmailFilePath = iEmailFilePath->Des();
+ TestCase().INFO_PRINTF2(_L("Email path: %S"), &ptrEmailFilePath);
+
+ iReplyToAddress = ObtainValueParameterL<TInt> (TestCase(),ActionParameters().Parameter(5));
+ TestCase().INFO_PRINTF2(_L("ReplyToField flag: %d"), iReplyToAddress);
+
+ return ETrue;
+ }
+
+/**
+ Function : ExecuteActionL
+ Description : Test framework entry point for CMtfTestActionVerifyReplyToAddress test action
+ @internalTechnology
+ @param none
+ @return void
+ @precondition none
+ @postcondition TestCase status EPass if tests passed otherwise EFail
+*/
+void CMtfTestActionVerifyReplyToAddress::ExecuteActionL()
+ {
+ TestCase().INFO_PRINTF2(_L("Test Action %S start..."), &KTestActionVerifyReplyToAddress);
+ if(LoadParametersL())
+ {
+ User::LeaveIfError(iFs.Connect());
+ CleanupClosePushL(iFs);
+ // Normally do not push an object that is a data member of another object.
+ // But in this case we want to close early if we get a leave.
+ // Otherwise the iFs would be open till the thread had begun to die.
+
+ if(TestCase().TestStepResult() == EPass)
+ {
+ CMsvEntry* recvMsvEntry = iSession->GetEntryL(KMsvRootIndexEntryId);
+ CleanupStack::PushL(recvMsvEntry);
+ CMsvEntry* sentMsvEntry = iSession->GetEntryL(KMsvRootIndexEntryId);
+ CleanupStack::PushL(sentMsvEntry);
+
+ for(TInt i=0; i<iInboxSelectionList->Count(); i++)
+ {
+ recvMsvEntry->SetEntryL(iInboxSelectionList->At(i));
+ TMsvEntry recvEntry = recvMsvEntry->Entry();
+ for(TInt j=0; j<iSentSelectionList->Count(); j++)
+ {
+ sentMsvEntry->SetEntryL(iSentSelectionList->At(j));
+ TMsvEntry sentEntry = sentMsvEntry->Entry();
+ if(recvEntry.iDescription.Compare(sentEntry.iDescription) == 0)
+ {
+ if(! ReplyToHeaderFieldCompareL(sentEntry, iEmailFilePath->Des(), iSession))
+ {
+ TestCase().INFO_PRINTF2(_L("Test %d failed"), j+1);
+ TestCase().SetTestStepResult(EFail);
+ }
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy(2, recvMsvEntry); // recvMsvEntry, sentMsvEntry
+ }
+ CleanupStack::PopAndDestroy(&iFs);
+ }
+
+ TestCase().INFO_PRINTF1( _L("Test Action CMtfTestActionVerifyEmail Completed") );
+ TestCase().ActionCompletedL(*this);
+ }
+
+TBool CMtfTestActionVerifyReplyToAddress::ReplyToHeaderFieldCompareL(TMsvEntry& aSentEntry, const TDesC& aFileName, CMsvSession* aSession)
+ {
+ TBool ret = ETrue;
+
+ // If Reply-To address exists in email header then...
+ if(iReplyToAddress)
+ {
+ // Read Reply-To field from sample email txt file
+ RFileReadStream rdStream;
+ User::LeaveIfError(rdStream.Open(iFs, aFileName, EFileRead|EFileStreamText));
+
+ if(IsEofL(rdStream))
+ {
+ ret = EFalse;
+ return ret;
+ }
+
+ TBuf8<256> line;
+ TChar char_LF('\n');
+ line.Zero();
+
+ do
+ {
+ rdStream.ReadL(line, char_LF);
+ if(line.Compare(KReplyToField)==0)
+ {
+ // Break from loop if expected Reply-To field found
+ break;
+ }
+ }
+ while(!IsEofL(rdStream));
+
+ rdStream.Close(); // End of reading stream
+
+ // aSentEntry - Identifier of the original sent email identified by TMsvEntry
+ CMsvEntry* msvEntry = aSession->GetEntryL(aSentEntry.Id());
+ CleanupStack::PushL(msvEntry);
+
+ msvEntry->SetEntryL(aSentEntry.Id());
+
+ CMsvStore* store = msvEntry->ReadStoreL();
+ CleanupStack::PushL(store);
+
+ CImHeader* header = CImHeader::NewLC();
+
+ header->RestoreL(*store);
+ // Read Reply-To address from email header
+ TPtrC line2 = header->ReplyTo();
+
+ TestCase().INFO_PRINTF2(_L("Reply-To address from actual sent message as stored in the Message store: %S"), &line2);
+
+ TBuf16<256> tmp;
+ tmp.Copy(line);
+
+ TBuf16<256> line_16;
+
+ // Extract just the Reply-To address without the initial tag and trailing CR-LF characters
+ for(TInt n=10; n<tmp.Length()-2; n++)
+ {
+ line_16.Append(tmp[n]);
+ }
+
+ // Compare if user-set Reply-To address in sample email txt file equals the one set by system in email header
+ if(line_16.Compare(line2) != 0)
+ {
+ ret = EFalse;
+ }
+
+ CleanupStack::PopAndDestroy(header);
+ CleanupStack::PopAndDestroy(store);
+ CleanupStack::PopAndDestroy(msvEntry);
+
+ }
+ // else no Reply-To address exists in email header...
+ else
+ {
+ // Check if Reply-To address is set correctly from default settings
+ CEmailAccounts* accounts = CEmailAccounts::NewL();
+ CleanupStack::PushL(accounts);
+ CImSmtpSettings* settings = new(ELeave) CImSmtpSettings();
+ CleanupStack::PushL(settings);
+ CImIAPPreferences* smtpIAP = CImIAPPreferences::NewLC();
+
+ TSmtpAccount smtpAccountId = accounts->CreateSmtpAccountL(_L("SMTP"),*settings, *smtpIAP, EFalse);
+ accounts->SetDefaultSmtpAccountL(smtpAccountId);
+ accounts->PopulateDefaultSmtpSettingsL(*settings, *smtpIAP);
+
+ CImIAPPreferences *popPrefs = CImIAPPreferences::NewLC();
+ CImPop3Settings *popSettings = new (ELeave) CImPop3Settings;
+ CleanupStack::PushL(popSettings);
+
+ accounts->PopulateDefaultPopSettingsL(*popSettings, *popPrefs);
+
+ // TestAction CreatePop3Service doesn't save settings to central repository,
+ // so default settings are reloaded
+ CMtfTestActionUtilsPopScripts::ReadPopSettingsFromConfigurationFileL(
+ TestCase(), KSettingsFile, *popSettings, *popPrefs, *settings, *smtpIAP);
+
+ TPtrC defaultReplyToAddress = settings->ReplyToAddress();
+
+ TestCase().INFO_PRINTF2(_L("Default ReplyTo Address: %S"), &defaultReplyToAddress);
+
+ // Format the Reply-To address field
+ HBufC* formatedAddress = CreateFormattedAddressLC(defaultReplyToAddress, settings->EmailAlias());
+ TPtr ptrFormatedAddress = formatedAddress->Des();
+ TestCase().INFO_PRINTF2(_L("Formated ReplyTo Address: %S"), &ptrFormatedAddress);
+
+ // aSentEntry - Identifier of the original sent email identified by TMsvEntry
+ CMsvEntry* msvEntry = aSession->GetEntryL(aSentEntry.Id());
+ CleanupStack::PushL(msvEntry);
+
+ msvEntry->SetEntryL(aSentEntry.Id());
+ CMsvStore* store = msvEntry->ReadStoreL();
+ CleanupStack::PushL(store);
+
+ CImHeader* header = CImHeader::NewLC();
+
+ header->RestoreL(*store);
+ // Read Reply-To address from email header
+ TPtrC usedReplyToAddress = header->ReplyTo();
+
+ TestCase().INFO_PRINTF2(_L("Reply-To address from actual sent message as stored in the Message store: %S"), &usedReplyToAddress);
+
+ // Compare if default Reply-To address equals the one set by system in email header
+ if(ptrFormatedAddress.Compare(usedReplyToAddress) !=0)
+ {
+ ret = EFalse;
+ }
+
+ CleanupStack::PopAndDestroy(header);
+ CleanupStack::PopAndDestroy(store);
+ CleanupStack::PopAndDestroy(msvEntry);
+ CleanupStack::PopAndDestroy(formatedAddress);
+ CleanupStack::PopAndDestroy(popSettings);
+ CleanupStack::PopAndDestroy(popPrefs);
+ CleanupStack::PopAndDestroy(smtpIAP);
+ CleanupStack::PopAndDestroy(settings);
+ CleanupStack::PopAndDestroy(accounts);
+ }
+ return ret;
+ }
+
+/**
+ IsEofL()
+ Checks if the current position of read stream reached end of file
+*/
+TBool CMtfTestActionVerifyReplyToAddress::IsEofL(RReadStream& aReadStream)
+ {
+ TStreamPos streamPos = aReadStream.Source()->TellL(MStreamBuf::ERead);
+ TInt streamSize = aReadStream.Source()->SizeL();
+
+ if(streamPos >= streamSize)
+ return ETrue;
+
+ return EFalse;
+ }
+
+/**
+ CreateFormattedAddressL()
+ Re-used code from src/common/generic/messaging/email/smtpservermtm/src/imsmsend.cpp#057
+ Creates a new HBufC* containing the concateneatd alias and address strings
+*/
+HBufC* CMtfTestActionVerifyReplyToAddress::CreateFormattedAddressLC(const TDesC& aString, const TDesC& aAlias)
+ {
+ TImMessageField msgField;
+
+ // Make a buffer...
+ TInt strLen = aString.Length();
+ TInt aliasLen = aAlias.Length();
+
+ HBufC* outString = HBufC::NewLC(strLen+aliasLen+5);
+ HBufC* buffer = HBufC::NewL(strLen);
+
+ *buffer = msgField.GetValidInternetEmailAddressFromString(aString);
+
+ if (aliasLen)
+ {
+ outString->Des().Format(KSmtpEmailAddressAndAliasFmtStr,&aAlias,buffer);
+ }
+ else
+ {
+ *outString = *buffer; // just copy email address; as there's no alias to be added
+ }
+
+ delete buffer;
+ return outString;
+ }
+