Beef up CJS_Document method coverage.

Also alphabetize mailDoc method position in .cpp file.

Change-Id: Ifb53e9a6f5f165bb41b865d51dae15e3bc84c4c7
Reviewed-on: https://pdfium-review.googlesource.com/c/43972
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fxjs/cjs_document.cpp b/fxjs/cjs_document.cpp
index 9899deb..f682ffd 100644
--- a/fxjs/cjs_document.cpp
+++ b/fxjs/cjs_document.cpp
@@ -166,6 +166,7 @@
     {"importAnXFDF", importAnXFDF_static},
     {"importTextData", importTextData_static},
     {"insertPages", insertPages_static},
+    {"mailDoc", mailDoc_static},
     {"mailForm", mailForm_static},
     {"print", print_static},
     {"removeField", removeField_static},
@@ -174,8 +175,7 @@
     {"removeIcon", removeIcon_static},
     {"saveAs", saveAs_static},
     {"submitForm", submitForm_static},
-    {"syncAnnotScan", syncAnnotScan_static},
-    {"mailDoc", mailDoc_static}};
+    {"syncAnnotScan", syncAnnotScan_static}};
 
 int CJS_Document::ObjDefnID = -1;
 const char CJS_Document::kName[] = "Document";
@@ -375,6 +375,49 @@
   return CJS_Result::Success();
 }
 
+CJS_Result CJS_Document::mailDoc(
+    CJS_Runtime* pRuntime,
+    const std::vector<v8::Local<v8::Value>>& params) {
+  // TODO(tsepez): Check maximum number of allowed params.
+  size_t nLength = params.size();
+  bool bUI = true;
+  WideString cTo;
+  WideString cCc;
+  WideString cBcc;
+  WideString cSubject;
+  WideString cMsg;
+
+  if (nLength > 0 && params[0]->IsObject()) {
+    v8::Local<v8::Object> pObj = pRuntime->ToObject(params[0]);
+    bUI = pRuntime->ToBoolean(pRuntime->GetObjectProperty(pObj, L"bUI"));
+    cTo = pRuntime->ToWideString(pRuntime->GetObjectProperty(pObj, L"cTo"));
+    cCc = pRuntime->ToWideString(pRuntime->GetObjectProperty(pObj, L"cCc"));
+    cBcc = pRuntime->ToWideString(pRuntime->GetObjectProperty(pObj, L"cBcc"));
+    cSubject =
+        pRuntime->ToWideString(pRuntime->GetObjectProperty(pObj, L"cSubject"));
+    cMsg = pRuntime->ToWideString(pRuntime->GetObjectProperty(pObj, L"cMsg"));
+  } else {
+    if (nLength > 0)
+      bUI = pRuntime->ToBoolean(params[0]);
+    if (nLength > 1)
+      cTo = pRuntime->ToWideString(params[1]);
+    if (nLength > 2)
+      cCc = pRuntime->ToWideString(params[2]);
+    if (nLength > 3)
+      cBcc = pRuntime->ToWideString(params[3]);
+    if (nLength > 4)
+      cSubject = pRuntime->ToWideString(params[4]);
+    if (nLength > 5)
+      cMsg = pRuntime->ToWideString(params[5]);
+  }
+
+  pRuntime->BeginBlock();
+  CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv();
+  pFormFillEnv->JS_docmailForm(nullptr, 0, bUI, cTo, cSubject, cCc, cBcc, cMsg);
+  pRuntime->EndBlock();
+  return CJS_Result::Success();
+}
+
 // exports the form data and mails the resulting fdf file as an attachment to
 // all recipients.
 // comment: need reader supports
@@ -649,49 +692,6 @@
   return CJS_Result::Success();
 }
 
-CJS_Result CJS_Document::mailDoc(
-    CJS_Runtime* pRuntime,
-    const std::vector<v8::Local<v8::Value>>& params) {
-  // TODO(tsepez): Check maximum number of allowed params.
-  size_t nLength = params.size();
-  bool bUI = true;
-  WideString cTo;
-  WideString cCc;
-  WideString cBcc;
-  WideString cSubject;
-  WideString cMsg;
-
-  if (nLength > 0 && params[0]->IsObject()) {
-    v8::Local<v8::Object> pObj = pRuntime->ToObject(params[0]);
-    bUI = pRuntime->ToBoolean(pRuntime->GetObjectProperty(pObj, L"bUI"));
-    cTo = pRuntime->ToWideString(pRuntime->GetObjectProperty(pObj, L"cTo"));
-    cCc = pRuntime->ToWideString(pRuntime->GetObjectProperty(pObj, L"cCc"));
-    cBcc = pRuntime->ToWideString(pRuntime->GetObjectProperty(pObj, L"cBcc"));
-    cSubject =
-        pRuntime->ToWideString(pRuntime->GetObjectProperty(pObj, L"cSubject"));
-    cMsg = pRuntime->ToWideString(pRuntime->GetObjectProperty(pObj, L"cMsg"));
-  } else {
-    if (nLength > 0)
-      bUI = pRuntime->ToBoolean(params[0]);
-    if (nLength > 1)
-      cTo = pRuntime->ToWideString(params[1]);
-    if (nLength > 2)
-      cCc = pRuntime->ToWideString(params[2]);
-    if (nLength > 3)
-      cBcc = pRuntime->ToWideString(params[3]);
-    if (nLength > 4)
-      cSubject = pRuntime->ToWideString(params[4]);
-    if (nLength > 5)
-      cMsg = pRuntime->ToWideString(params[5]);
-  }
-
-  pRuntime->BeginBlock();
-  CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv();
-  pFormFillEnv->JS_docmailForm(nullptr, 0, bUI, cTo, cSubject, cCc, cBcc, cMsg);
-  pRuntime->EndBlock();
-  return CJS_Result::Success();
-}
-
 CJS_Result CJS_Document::get_author(CJS_Runtime* pRuntime) {
   return getPropertyInternal(pRuntime, "Author");
 }
diff --git a/fxjs/cjs_document.h b/fxjs/cjs_document.h
index 5232803..ed8bcc0 100644
--- a/fxjs/cjs_document.h
+++ b/fxjs/cjs_document.h
@@ -99,6 +99,7 @@
   JS_STATIC_METHOD(importAnXFDF, CJS_Document);
   JS_STATIC_METHOD(importTextData, CJS_Document);
   JS_STATIC_METHOD(insertPages, CJS_Document);
+  JS_STATIC_METHOD(mailDoc, CJS_Document);
   JS_STATIC_METHOD(mailForm, CJS_Document);
   JS_STATIC_METHOD(print, CJS_Document);
   JS_STATIC_METHOD(removeField, CJS_Document);
@@ -108,7 +109,6 @@
   JS_STATIC_METHOD(saveAs, CJS_Document);
   JS_STATIC_METHOD(submitForm, CJS_Document);
   JS_STATIC_METHOD(syncAnnotScan, CJS_Document);
-  JS_STATIC_METHOD(mailDoc, CJS_Document);
 
  private:
   static int ObjDefnID;
diff --git a/testing/resources/javascript/document_methods.in b/testing/resources/javascript/document_methods.in
index 66d5484f..0188d7c 100644
--- a/testing/resources/javascript/document_methods.in
+++ b/testing/resources/javascript/document_methods.in
@@ -187,7 +187,11 @@
   // Argument can not be negative.
   expectError('this.getNthFieldName(-1)');
 
-  // TODO(tsepez): test success cases.
+  // Argument can not be huge.
+  expectError('this.getNthFieldName(400000)');
+
+  // TODO(tsepez): add field object so this case works.
+  expectError('this.getNthFieldName(0)');
 }
 
 function testGetPageNthWord() {
@@ -229,29 +233,37 @@
 }
 
 function testGetPrintParams() {
-   // Method is present.
-   expect('typeof this.getPrintParams', 'function');
+  // Method is present.
+  expect('typeof this.getPrintParams', 'function');
 
-  // TODO(tsepez): test success cases.
+  // Method always returns in error.
+  expectError('this.getPrintParams()');
+  expectError('this.getPrintParams(42)');
 }
 
 function testGotoNamedDest() {
-   // Method is present.
-   expect('typeof this.gotoNamedDest', 'function');
+  // Method is present.
+  expect('typeof this.gotoNamedDest', 'function');
 
-   // Method needs exactly one argument.
-   expectError('this.gotoNamedDest()');
-   expectError('this.gotoNamedDest(1, 2)');
+  // Method needs exactly one argument.
+  expectError('this.gotoNamedDest()');
+  expectError('this.gotoNamedDest(1, 2)');
 
-   // TODO(tonikitoo): test success cases.
+  // TODO(tsepez): add actual named dest matching this.
+  expectError('this.gotoNamedDest("chicago")');
 }
 
 function testMailDoc() {
-   // Method is present.
-   expect('typeof this.mailDoc', 'function');
+  // Method is present.
+  expect('typeof this.mailDoc', 'function');
 
   // TODO(tsepez): test with no permissions.
-  // TODO(tsepez): test success cases.
+
+  // Success cases.
+  expect('this.mailDoc(true)', undefined);
+  expect('this.mailDoc(false, "user@example.com", "cc@example.com", ' +
+             '"bcc@example.com", "Lottery Winner", "You won the lottery!")',
+         undefined);
 }
 
 function testMailForm() {
@@ -259,7 +271,12 @@
    expect('typeof this.mailForm', 'function');
 
   // TODO(tsepez): test with no permissions.
-  // TODO(tsepez): test success cases.
+
+  // Success cases.
+  expect('this.mailForm(true)', undefined);
+  expect('this.mailForm(false, "user@example.com", "cc@example.com", ' +
+             '"bcc@example.com", "Lottery Winner", "You won the lottery!")',
+         undefined);
 }
 
 function testPrint() {
@@ -285,7 +302,10 @@
    expect('typeof this.resetForm', 'function');
 
   // TODO(tsepez): test with no permissions.
-  // TODO(tsepez): test success cases.
+
+  // TODO(tsepez): Add form to document to match these arguments.
+  expect('this.resetForm()', undefined);
+  expect('this.resetForm("myform")', undefined);
 }
 
 function testSubmitForm() {
@@ -295,7 +315,8 @@
   // Method requires at least one argument.
   expectError('this.submitForm()');
 
-  // TODO(tsepez): test success cases.
+  // TODO(tsepez): Add form to document to match these arguments.
+  expect('this.submitForm("myform", true, true, ["name", "age"])', undefined);
 }
 
 try {
diff --git a/testing/resources/javascript/document_methods_expected.txt b/testing/resources/javascript/document_methods_expected.txt
index 4a2c4d7..01bf0ed 100644
--- a/testing/resources/javascript/document_methods_expected.txt
+++ b/testing/resources/javascript/document_methods_expected.txt
@@ -89,6 +89,8 @@
 Alert: PASS: typeof this.getNthFieldName = function
 Alert: PASS: this.getNthFieldName() threw error Document.getNthFieldName: Incorrect number of parameters passed to function.
 Alert: PASS: this.getNthFieldName(-1) threw error Document.getNthFieldName: Incorrect parameter value.
+Alert: PASS: this.getNthFieldName(400000) threw error Document.getNthFieldName: Object no longer exists.
+Alert: PASS: this.getNthFieldName(0) threw error Document.getNthFieldName: Object no longer exists.
 Alert: PASS: typeof this.getPageNthWord = function
 Alert: PASS: this.getPageNthWord(0, 0, true, "clams", [1, 2]) = Hello,
 Alert: PASS: this.getPageNthWord(-1, 0, true) threw error Document.getPageNthWord: Incorrect parameter value.
@@ -99,14 +101,28 @@
 Alert: PASS: this.getPageNumWords(-1) threw error Document.getPageNumWords: Incorrect parameter value.
 Alert: PASS: this.getPageNumWords(6) threw error Document.getPageNumWords: Incorrect parameter value.
 Alert: PASS: typeof this.getPrintParams = function
+Alert: PASS: this.getPrintParams() threw error Document.getPrintParams: Operation not supported.
+Alert: PASS: this.getPrintParams(42) threw error Document.getPrintParams: Operation not supported.
 Alert: PASS: typeof this.gotoNamedDest = function
 Alert: PASS: this.gotoNamedDest() threw error Document.gotoNamedDest: Incorrect number of parameters passed to function.
 Alert: PASS: this.gotoNamedDest(1, 2) threw error Document.gotoNamedDest: Incorrect number of parameters passed to function.
+Alert: PASS: this.gotoNamedDest("chicago") threw error Document.gotoNamedDest: Object no longer exists.
 Alert: PASS: typeof this.mailDoc = function
+Mail Msg: 1, to=, cc=, bcc=, subject=, body=
+Alert: PASS: this.mailDoc(true) = undefined
+Mail Msg: 0, to=user@example.com, cc=cc@example.com, bcc=bcc@example.com, subject=Lottery Winner, body=You won the lottery!
+Alert: PASS: this.mailDoc(false, "user@example.com", "cc@example.com", "bcc@example.com", "Lottery Winner", "You won the lottery!") = undefined
 Alert: PASS: typeof this.mailForm = function
+Mail Msg: 1, to=, cc=, bcc=, subject=, body=
+Alert: PASS: this.mailForm(true) = undefined
+Mail Msg: 0, to=user@example.com, cc=cc@example.com, bcc=bcc@example.com, subject=Lottery Winner, body=You won the lottery!
+Alert: PASS: this.mailForm(false, "user@example.com", "cc@example.com", "bcc@example.com", "Lottery Winner", "You won the lottery!") = undefined
 Alert: PASS: typeof this.print = function
 Alert: PASS: typeof this.removeField = function
 Alert: PASS: this.removeField() threw error Document.removeField: Incorrect number of parameters passed to function.
 Alert: PASS: typeof this.resetForm = function
+Alert: PASS: this.resetForm() = undefined
+Alert: PASS: this.resetForm("myform") = undefined
 Alert: PASS: typeof this.submitForm = function
 Alert: PASS: this.submitForm() threw error Document.submitForm: Incorrect number of parameters passed to function.
+Alert: PASS: this.submitForm("myform", true, true, ["name", "age"]) = undefined