Bug 547027 - Create a framework for MAPI tests. r=standard8,jorgk
This commit is contained in:
Родитель
72159e289e
Коммит
4b16fef452
|
@ -167,12 +167,7 @@ ULONG FAR PASCAL MAPISendMail (LHANDLE lhSession, ULONG ulUIParam, nsMapiMessage
|
|||
|
||||
if (!lhSession || pNsMapi->IsValidSession(lhSession) != S_OK)
|
||||
{
|
||||
FLAGS LoginFlag = 0;
|
||||
if ( (flFlags & MAPI_LOGON_UI) && (flFlags & MAPI_NEW_SESSION) )
|
||||
LoginFlag = MAPI_LOGON_UI | MAPI_NEW_SESSION ;
|
||||
else if (flFlags & MAPI_LOGON_UI)
|
||||
LoginFlag = MAPI_LOGON_UI ;
|
||||
|
||||
FLAGS LoginFlag = flFlags & (MAPI_LOGON_UI | MAPI_NEW_SESSION);
|
||||
hr = MAPILogon(ulUIParam, nullptr, nullptr, LoginFlag, 0, &lhSession);
|
||||
if (hr != SUCCESS_SUCCESS)
|
||||
return MAPI_E_LOGIN_FAILURE ;
|
||||
|
@ -213,12 +208,7 @@ ULONG FAR PASCAL MAPISendMailW(LHANDLE lhSession, ULONG ulUIParam, nsMapiMessage
|
|||
|
||||
if (!lhSession || pNsMapi->IsValidSession(lhSession) != S_OK)
|
||||
{
|
||||
FLAGS LoginFlag = 0;
|
||||
if ((flFlags & MAPI_LOGON_UI) && (flFlags & MAPI_NEW_SESSION))
|
||||
LoginFlag = MAPI_LOGON_UI | MAPI_NEW_SESSION;
|
||||
else if (flFlags & MAPI_LOGON_UI)
|
||||
LoginFlag = MAPI_LOGON_UI;
|
||||
|
||||
FLAGS LoginFlag = flFlags & (MAPI_LOGON_UI | MAPI_NEW_SESSION);
|
||||
hr = MAPILogon(ulUIParam, nullptr, nullptr, LoginFlag, 0, &lhSession);
|
||||
if (hr != SUCCESS_SUCCESS)
|
||||
return MAPI_E_LOGIN_FAILURE;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "nsMsgUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsIArray.h"
|
||||
#include "nsArrayUtils.h"
|
||||
|
@ -44,9 +45,13 @@
|
|||
|
||||
extern mozilla::LazyLogModule MAPI; // defined in msgMapiImp.cpp
|
||||
|
||||
class nsMAPISendListener : public nsIMsgSendListener
|
||||
class MAPISendListener : public nsIMsgSendListener,
|
||||
public mozilla::Monitor
|
||||
{
|
||||
public:
|
||||
MAPISendListener()
|
||||
: Monitor("MAPISendListener monitor"),
|
||||
m_done(false) {}
|
||||
|
||||
// nsISupports interface
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
@ -63,11 +68,9 @@ public:
|
|||
/* void OnStopSending (in string aMsgID, in nsresult aStatus, in wstring aMsg, in nsIFile returnFile); */
|
||||
NS_IMETHOD OnStopSending(const char *aMsgID, nsresult aStatus, const char16_t *aMsg,
|
||||
nsIFile *returnFile) {
|
||||
PR_CEnterMonitor(this);
|
||||
PR_CNotifyAll(this);
|
||||
m_done = true;
|
||||
PR_CExitMonitor(this);
|
||||
return NS_OK ;
|
||||
NotifyAll();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void OnSendNotPerformed */
|
||||
|
@ -79,30 +82,52 @@ public:
|
|||
/* void OnGetDraftFolderURI (); */
|
||||
NS_IMETHOD OnGetDraftFolderURI(const char *aFolderURI) {return NS_OK;}
|
||||
|
||||
static nsresult CreateMAPISendListener( nsIMsgSendListener **ppListener);
|
||||
|
||||
bool IsDone() { return m_done ; }
|
||||
|
||||
protected :
|
||||
nsMAPISendListener() {
|
||||
m_done = false;
|
||||
}
|
||||
|
||||
bool m_done;
|
||||
private:
|
||||
virtual ~nsMAPISendListener() { }
|
||||
|
||||
bool m_done;
|
||||
virtual ~MAPISendListener() { }
|
||||
};
|
||||
|
||||
/// Helper for setting up the hidden window for blind MAPI.
|
||||
class MOZ_STACK_CLASS AutoHiddenWindow {
|
||||
public:
|
||||
explicit AutoHiddenWindow(nsresult &rv)
|
||||
: mAppService(do_GetService("@mozilla.org/appshell/appShellService;1"))
|
||||
{
|
||||
mCreatedHiddenWindow = false;
|
||||
rv = mAppService->GetHiddenDOMWindow(getter_AddRefs(mHiddenWindow));
|
||||
if (rv == NS_ERROR_FAILURE)
|
||||
{
|
||||
// Try to get a hidden window. If it doesn't exist, create a hidden
|
||||
// window for us to use.
|
||||
rv = mAppService->CreateHiddenWindow();
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
mCreatedHiddenWindow = true;
|
||||
rv = mAppService->GetHiddenDOMWindow(getter_AddRefs(mHiddenWindow));
|
||||
}
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
}
|
||||
~AutoHiddenWindow()
|
||||
{
|
||||
if (mCreatedHiddenWindow)
|
||||
mAppService->DestroyHiddenWindow();
|
||||
}
|
||||
mozIDOMWindowProxy *operator->()
|
||||
{
|
||||
return mHiddenWindow;
|
||||
}
|
||||
operator mozIDOMWindowProxy *()
|
||||
{
|
||||
return mHiddenWindow;
|
||||
}
|
||||
private:
|
||||
nsCOMPtr<nsIAppShellService> mAppService;
|
||||
nsCOMPtr<mozIDOMWindowProxy> mHiddenWindow;
|
||||
bool mCreatedHiddenWindow;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsMAPISendListener, nsIMsgSendListener)
|
||||
|
||||
nsresult nsMAPISendListener::CreateMAPISendListener( nsIMsgSendListener **ppListener)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(ppListener) ;
|
||||
NS_ADDREF(*ppListener = new nsMAPISendListener());
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMPL_ISUPPORTS(MAPISendListener, nsIMsgSendListener)
|
||||
|
||||
bool nsMapiHook::isMapiService = false;
|
||||
|
||||
|
@ -262,20 +287,15 @@ nsMapiHook::IsBlindSendAllowed()
|
|||
// this is used for Send without UI
|
||||
nsresult nsMapiHook::BlindSendMail (unsigned long aSession, nsIMsgCompFields * aCompFields)
|
||||
{
|
||||
nsresult rv = NS_OK ;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!IsBlindSendAllowed())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
/** create nsIMsgComposeParams obj and other fields to populate it **/
|
||||
// Get a hidden window to use for compose.
|
||||
AutoHiddenWindow hiddenWindow(rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<mozIDOMWindowProxy> hiddenWindow;
|
||||
// get parent window
|
||||
nsCOMPtr<nsIAppShellService> appService = do_GetService( "@mozilla.org/appshell/appShellService;1", &rv);
|
||||
if (NS_FAILED(rv)|| (!appService) ) return rv ;
|
||||
|
||||
rv = appService->GetHiddenDOMWindow(getter_AddRefs(hiddenWindow));
|
||||
if ( NS_FAILED(rv) ) return rv ;
|
||||
// smtp password and Logged in used IdKey from MapiConfig (session obj)
|
||||
nsMAPIConfiguration * pMapiConfig = nsMAPIConfiguration::GetMAPIConfiguration() ;
|
||||
if (!pMapiConfig) return NS_ERROR_FAILURE ; // get the singelton obj
|
||||
|
@ -294,9 +314,7 @@ nsresult nsMapiHook::BlindSendMail (unsigned long aSession, nsIMsgCompFields * a
|
|||
if (NS_FAILED(rv) ) return rv ;
|
||||
|
||||
// create a send listener to get back the send status
|
||||
nsCOMPtr <nsIMsgSendListener> sendListener ;
|
||||
rv = nsMAPISendListener::CreateMAPISendListener(getter_AddRefs(sendListener)) ;
|
||||
if (NS_FAILED(rv) || (!sendListener) ) return rv;
|
||||
RefPtr<MAPISendListener> sendListener = new MAPISendListener;
|
||||
|
||||
// create the compose params object
|
||||
nsCOMPtr<nsIMsgComposeParams> pMsgComposeParams (do_CreateInstance(NS_MSGCOMPOSEPARAMS_CONTRACTID, &rv));
|
||||
|
@ -315,33 +333,31 @@ nsresult nsMapiHook::BlindSendMail (unsigned long aSession, nsIMsgCompFields * a
|
|||
|
||||
// create the nsIMsgCompose object to send the object
|
||||
nsCOMPtr<nsIMsgCompose> pMsgCompose (do_CreateInstance(NS_MSGCOMPOSE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv) || (!pMsgCompose) ) return rv ;
|
||||
|
||||
/** initialize nsIMsgCompose, Send the message, wait for send completion response **/
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = pMsgCompose->Initialize(pMsgComposeParams, hiddenWindow, nullptr);
|
||||
if (NS_FAILED(rv)) return rv ;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If we're in offline mode, we'll need to queue it for later. No point in trying to send it.
|
||||
return pMsgCompose->SendMsg(WeAreOffline() ? nsIMsgSend::nsMsgQueueForLater : nsIMsgSend::nsMsgDeliverNow,
|
||||
pMsgId, nullptr, nullptr, nullptr);
|
||||
if (NS_FAILED(rv)) return rv ;
|
||||
// If we're in offline mode, we'll need to queue it for later.
|
||||
rv = pMsgCompose->SendMsg(WeAreOffline() ? nsIMsgSend::nsMsgQueueForLater
|
||||
: nsIMsgSend::nsMsgDeliverNow,
|
||||
pMsgId, nullptr, nullptr, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// assign to interface pointer from nsCOMPtr to facilitate typecast below
|
||||
nsIMsgSendListener * pSendListener = sendListener ;
|
||||
// We need to wait to make sure that we only return when the send is
|
||||
// completed. If we're offline, we're not sending yet, so don't bother
|
||||
// waiting.
|
||||
if (WeAreOffline())
|
||||
return NS_OK;
|
||||
|
||||
// we need to wait here to make sure that we return only after send is completed
|
||||
// so we will have a event loop here which will process the events till the Send IsDone.
|
||||
nsCOMPtr<nsIThread> thread(do_GetCurrentThread());
|
||||
while ( !((nsMAPISendListener *) pSendListener)->IsDone() )
|
||||
while (!sendListener->IsDone())
|
||||
{
|
||||
PR_CEnterMonitor(pSendListener);
|
||||
PR_CWait(pSendListener, PR_MicrosecondsToInterval(1000UL));
|
||||
PR_CExitMonitor(pSendListener);
|
||||
mozilla::MonitorAutoLock mal(*sendListener);
|
||||
sendListener->Wait(mozilla::TimeDuration::FromMilliseconds(1000UL));
|
||||
NS_ProcessPendingEvents(thread);
|
||||
}
|
||||
|
||||
return rv ;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMapiHook::HandleAttachments (nsIMsgCompFields * aCompFields, int32_t aFileCount,
|
||||
|
@ -907,9 +923,7 @@ nsresult nsMapiHook::ShowComposerWindow (unsigned long aSession, nsIMsgCompField
|
|||
nsresult rv = NS_OK ;
|
||||
|
||||
// create a send listener to get back the send status
|
||||
nsCOMPtr <nsIMsgSendListener> sendListener ;
|
||||
rv = nsMAPISendListener::CreateMAPISendListener(getter_AddRefs(sendListener)) ;
|
||||
if (NS_FAILED(rv) || (!sendListener) ) return rv ;
|
||||
RefPtr<MAPISendListener> sendListener = new MAPISendListener;
|
||||
|
||||
// create the compose params object
|
||||
nsCOMPtr<nsIMsgComposeParams> pMsgComposeParams (do_CreateInstance(NS_MSGCOMPOSEPARAMS_CONTRACTID, &rv));
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini']
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": "plugin:mozilla/xpcshell-test",
|
||||
|
||||
"rules": {
|
||||
"func-names": "off",
|
||||
"mozilla/import-headjs-globals": "error",
|
||||
"no-unused-vars": ["error", {
|
||||
"args": "none",
|
||||
"vars": "all",
|
||||
}],
|
||||
},
|
||||
};
|
|
@ -0,0 +1,199 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
var {MailServices} = ChromeUtils.import("resource:///modules/MailServices.jsm");
|
||||
var {ctypes} = ChromeUtils.import("resource:///modules/ctypes.jsm");
|
||||
var {localAccountUtils} = ChromeUtils.import("resource://testing-common/mailnews/localAccountUtils.js");
|
||||
|
||||
// Ensure the profile directory is set up.
|
||||
do_get_profile();
|
||||
|
||||
// Import fakeserver
|
||||
var {nsMailServer} = ChromeUtils.import("resource://testing-common/mailnews/maild.js");
|
||||
var {
|
||||
smtpDaemon,
|
||||
SMTP_RFC2821_handler,
|
||||
} = ChromeUtils.import("resource://testing-common/mailnews/smtpd.js");
|
||||
|
||||
var SMTP_PORT = 1024 + 120;
|
||||
var POP3_PORT = 1024 + 121;
|
||||
|
||||
// Setup the daemon and server
|
||||
function setupServerDaemon(handler) {
|
||||
if (!handler)
|
||||
handler = function(d) { return new SMTP_RFC2821_handler(d); };
|
||||
let daemon = new smtpDaemon();
|
||||
let server = new nsMailServer(handler, daemon);
|
||||
return [daemon, server];
|
||||
}
|
||||
|
||||
function getBasicSmtpServer() {
|
||||
// We need to have a default account for MAPI.
|
||||
localAccountUtils.loadLocalMailAccount();
|
||||
let incoming = localAccountUtils.create_incoming_server("pop3", POP3_PORT,
|
||||
"user", "password");
|
||||
let server = localAccountUtils.create_outgoing_server(SMTP_PORT,
|
||||
"user", "password");
|
||||
// We also need to have a working identity, including an email address.
|
||||
let account = MailServices.accounts.FindAccountForServer(incoming);
|
||||
localAccountUtils.associate_servers(account, server, true);
|
||||
let identity = account.defaultIdentity;
|
||||
identity.email = "tinderbox@tinderbox.invalid";
|
||||
MailServices.accounts.defaultAccount = account;
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a structure allowing access to all of the Simple MAPI functions.
|
||||
* The functions do not have the MAPI prefix on the variables. Also added are
|
||||
* the three structures needed for MAPI.
|
||||
*/
|
||||
function loadMAPILibrary() {
|
||||
// This is a hack to load the MAPI support in the current environment, as the
|
||||
// profile-after-change event is never sent out.
|
||||
var gMapiSupport = Cc["@mozilla.org/mapisupport;1"]
|
||||
.getService(Ci.nsIObserver);
|
||||
gMapiSupport.observe(null, "profile-after-change", null);
|
||||
// Set some preferences to make MAPI (particularly blind MAPI, aka work
|
||||
// without a dialog box) work properly.
|
||||
Services.prefs.setBoolPref("mapi.blind-send.enabled", true);
|
||||
Services.prefs.setBoolPref("mapi.blind-send.warn", false);
|
||||
|
||||
// The macros that are used in the definitions
|
||||
let WINAPI = ctypes.winapi_abi;
|
||||
let ULONG = ctypes.unsigned_long;
|
||||
let LHANDLE = ULONG.ptr;
|
||||
let LPSTR = ctypes.char.ptr;
|
||||
let LPVOID = ctypes.voidptr_t;
|
||||
let FLAGS = ctypes.unsigned_long;
|
||||
|
||||
// Define all of the MAPI structs we need to use.
|
||||
let functionData = {};
|
||||
functionData.MapiRecipDesc = new ctypes.StructType("gMapi.MapiRecipDesc", [
|
||||
{ulReserved: ULONG},
|
||||
{ulRecipClass: ULONG},
|
||||
{lpszName: LPSTR},
|
||||
{lpszAddress: LPSTR},
|
||||
{ulEIDSize: ULONG},
|
||||
{lpEntryID: LPVOID},
|
||||
]);
|
||||
let lpMapiRecipDesc = functionData.MapiRecipDesc.ptr;
|
||||
|
||||
functionData.MapiFileDesc = new ctypes.StructType("gMapi.MapiFileDesc", [
|
||||
{ulReserved: ULONG},
|
||||
{flFlags: ULONG},
|
||||
{nPosition: ULONG},
|
||||
{lpszPathName: LPSTR},
|
||||
{lpszFileName: LPSTR},
|
||||
{lpFileType: LPVOID},
|
||||
]);
|
||||
let lpMapiFileDesc = functionData.MapiFileDesc.ptr;
|
||||
|
||||
functionData.MapiMessage = new ctypes.StructType("gMapi.MapiMessage", [
|
||||
{ulReserved: ULONG},
|
||||
{lpszSubject: LPSTR},
|
||||
{lpszNoteText: LPSTR},
|
||||
{lpszMessageType: LPSTR},
|
||||
{lpszDateReceived: LPSTR},
|
||||
{lpszConversationID: LPSTR},
|
||||
{flFlags: FLAGS},
|
||||
{lpOriginator: lpMapiRecipDesc},
|
||||
{nRecipCount: ULONG},
|
||||
{lpRecips: lpMapiRecipDesc},
|
||||
{nFileCount: ULONG},
|
||||
{lpFiles: lpMapiFileDesc},
|
||||
]);
|
||||
let lpMapiMessage = functionData.MapiMessage.ptr;
|
||||
|
||||
// Load the MAPI library. We're using our definition instead of the global
|
||||
// MAPI definition.
|
||||
let mapi = ctypes.open("mozMapi32.dll");
|
||||
|
||||
// Load the MAPI functions,
|
||||
// see https://developer.mozilla.org/en-US/docs/Mozilla/js-ctypes/Using_js-ctypes/Declaring_types
|
||||
// for details. The first three parameters of the declaration are name, API flag and output value.
|
||||
// This is followed by input parameters.
|
||||
|
||||
// MAPIAddress is not supported.
|
||||
|
||||
functionData.DeleteMail = mapi.declare(
|
||||
"MAPIDeleteMail", WINAPI, ULONG,
|
||||
LHANDLE, // lhSession
|
||||
ULONG.ptr, // ulUIParam
|
||||
LPSTR, // lpszMessageID
|
||||
FLAGS, // flFlags
|
||||
ULONG); // ulReserved
|
||||
|
||||
// MAPIDetails is not supported.
|
||||
|
||||
functionData.FindNext = mapi.declare(
|
||||
"MAPIFindNext", WINAPI, ULONG,
|
||||
LHANDLE, // lhSession
|
||||
ULONG.ptr, // ulUIParam
|
||||
LPSTR, // lpszMessageType
|
||||
LPSTR, // lpszSeedMessageID
|
||||
FLAGS, // flFlags
|
||||
ULONG, // ulReserved
|
||||
LPSTR); // lpszMessageID
|
||||
|
||||
functionData.FreeBuffer = mapi.declare(
|
||||
"MAPIFreeBuffer", WINAPI, ULONG,
|
||||
LPVOID); // pv
|
||||
|
||||
functionData.Logoff = mapi.declare(
|
||||
"MAPILogoff", WINAPI, ULONG,
|
||||
LHANDLE, // lhSession
|
||||
ULONG.ptr, // ulUIParam
|
||||
FLAGS, // flFlags
|
||||
ULONG); // ulReserved
|
||||
|
||||
functionData.Logon = mapi.declare(
|
||||
"MAPILogon", WINAPI, ULONG,
|
||||
ULONG.ptr, // ulUIParam
|
||||
LPSTR, // lpszProfileName
|
||||
LPSTR, // lpszPassword
|
||||
FLAGS, // flFlags
|
||||
ULONG, // ulReserved
|
||||
LHANDLE.ptr); // lplhSession
|
||||
|
||||
functionData.ReadMail = mapi.declare(
|
||||
"MAPIReadMail", WINAPI, ULONG,
|
||||
LHANDLE, // lhSession
|
||||
ULONG.ptr, // ulUIParam
|
||||
LPSTR, // lpszMessageID
|
||||
FLAGS, // flFlags
|
||||
ULONG, // ulReserved
|
||||
lpMapiMessage.ptr); // *lppMessage
|
||||
|
||||
functionData.ResolveName = mapi.declare(
|
||||
"MAPIResolveName", WINAPI, ULONG,
|
||||
LHANDLE, // lhSession
|
||||
ULONG.ptr, // ulUIParam
|
||||
LPSTR, // lpszName
|
||||
FLAGS, // flFlags
|
||||
ULONG, // ulReserved
|
||||
lpMapiRecipDesc.ptr); // *lppRecip
|
||||
|
||||
// MAPISaveMail is not supported.
|
||||
|
||||
functionData.SendDocuments = mapi.declare(
|
||||
"MAPISendDocuments", WINAPI, ULONG,
|
||||
ULONG.ptr, // ulUIParam
|
||||
LPSTR, // lpszDelimChar
|
||||
LPSTR, // lpszFilePaths
|
||||
LPSTR, // lpszFileNames
|
||||
ULONG); // ulReserved
|
||||
|
||||
functionData.SendMail = mapi.declare(
|
||||
"MAPISendMail", WINAPI, ULONG,
|
||||
LHANDLE, // lhSession
|
||||
ULONG.ptr, // ulUIParam
|
||||
lpMapiMessage, // lpMessage
|
||||
FLAGS, // flFlags
|
||||
ULONG); // ulReserved
|
||||
|
||||
return functionData;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
load("../../../resources/mailShutdown.js");
|
|
@ -0,0 +1,40 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var {ctypes} = ChromeUtils.import("resource:///modules/ctypes.jsm");
|
||||
var {MimeParser} = ChromeUtils.import("resource:///modules/mimeParser.jsm");
|
||||
|
||||
function run_test() {
|
||||
// Set up an SMTP server and the MAPI daemon.
|
||||
getBasicSmtpServer();
|
||||
let [daemon, server] = setupServerDaemon();
|
||||
server.start(SMTP_PORT);
|
||||
let mapi = loadMAPILibrary();
|
||||
|
||||
// Build a message using the MAPI interface.
|
||||
let message = new mapi.MapiMessage();
|
||||
message.lpszSubject = ctypes.char.array()("Hello, MAPI!");
|
||||
message.lpszNoteText = ctypes.char.array()("I successfully sent a message!");
|
||||
message.lpszMessageType = ctypes.char.array()("");
|
||||
message.lpFiles = null;
|
||||
let recipient = new mapi.MapiRecipDesc();
|
||||
recipient.ulRecipClass = 1; /* MAPI_TO */
|
||||
recipient.lpszName = ctypes.char.array()("John Doe");
|
||||
recipient.lpszAddress = ctypes.char.array()("SMTP:john.doe@example.com");
|
||||
message.nRecipCount = 1;
|
||||
message.lpRecips = recipient.address();
|
||||
|
||||
// Use MAPISendMail to send this message.
|
||||
mapi.SendMail(null /* No session */, null /* No HWND */, message.address(),
|
||||
0x2 /* MAPI_NEW_SESSION */, 0);
|
||||
|
||||
// Check that the post has the correct information.
|
||||
let [headers, body] = MimeParser.extractHeadersAndBody(daemon.post);
|
||||
Assert.equal(headers.get("from")[0].email, "tinderbox@tinderbox.invalid");
|
||||
Assert.equal(headers.get("to")[0].email, "john.doe@example.com");
|
||||
Assert.equal(headers.get("subject"), "Hello, MAPI!");
|
||||
Assert.equal(body.trim(), "I successfully sent a message!");
|
||||
|
||||
server.stop();
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
[DEFAULT]
|
||||
head = head_mapi.js
|
||||
tail = tail_mapi.js
|
||||
run-sequentially = Need to use well-known port for SMTP.
|
||||
|
||||
[test_mapisendmail.js]
|
||||
skip-if = true # Not yet enabled, see bug 1526807.
|
|
@ -51,6 +51,7 @@ if CONFIG['MOZ_MAPI_SUPPORT']:
|
|||
'mapi/mapiDLL',
|
||||
'mapi/mapihook',
|
||||
]
|
||||
TEST_DIRS += ['mapi/test']
|
||||
|
||||
DIRS += [
|
||||
'build',
|
||||
|
|
Загрузка…
Ссылка в новой задаче