#include "ppapi/tests/test_file_chooser.h"
#include <stddef.h>
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_file_io.h"
#include "ppapi/cpp/dev/file_chooser_dev.h"
#include "ppapi/cpp/file_io.h"
#include "ppapi/cpp/trusted/file_chooser_trusted.h"
#include "ppapi/cpp/var.h"
namespace {
const char kTestFileContents[] = "Hello from PPAPI";
const size_t kTestFileContentsSizeBytes = sizeof(kTestFileContents) - 1;
}
REGISTER_TEST_CASE(FileChooser);
bool TestFileChooser::Init() {
return CheckTestingInterface() && EnsureRunningOverHTTP();
}
void TestFileChooser::RunTests(const std::string& filter) {
RUN_TEST(OpenSimple, filter);
RUN_TEST(OpenCancel, filter);
RUN_TEST(SaveAsSafeDefaultName, filter);
RUN_TEST(SaveAsUnsafeDefaultName, filter);
RUN_TEST(SaveAsCancel, filter);
RUN_TEST(SaveAsDangerousExecutableAllowed, filter);
RUN_TEST(SaveAsDangerousExecutableDisallowed, filter);
RUN_TEST(SaveAsDangerousExtensionListDisallowed, filter);
}
bool TestFileChooser::WriteDefaultContentsToFile(const pp::FileRef& file_ref) {
TestCompletionCallback fileio_callback(instance_->pp_instance(),
callback_type());
pp::FileIO fileio(instance());
fileio_callback.WaitForResult(
fileio.Open(file_ref, PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE,
fileio_callback.GetCallback()));
if (fileio_callback.result() != PP_OK)
return false;
fileio_callback.WaitForResult(fileio.Write(0, kTestFileContents,
kTestFileContentsSizeBytes,
fileio_callback.GetCallback()));
return fileio_callback.result() == kTestFileContentsSizeBytes;
}
std::string TestFileChooser::TestOpenSimple() {
pp::FileChooser_Dev file_chooser(instance(), PP_FILECHOOSERMODE_OPEN, "*");
ASSERT_FALSE(file_chooser.is_null());
TestCompletionCallbackWithOutput<std::vector<pp::FileRef>>
filechooser_callback(instance_->pp_instance(), callback_type());
filechooser_callback.WaitForResult(
file_chooser.Show(filechooser_callback.GetCallback()));
const std::vector<pp::FileRef>& output_ref = filechooser_callback.output();
ASSERT_EQ(1u, output_ref.size());
TestCompletionCallback fileio_callback(instance_->pp_instance(),
callback_type());
pp::FileIO fileio(instance());
fileio_callback.WaitForResult(fileio.Open(
output_ref.front(), PP_FILEOPENFLAG_READ, fileio_callback.GetCallback()));
ASSERT_EQ(PP_OK, fileio_callback.result());
PASS();
}
std::string TestFileChooser::TestOpenCancel() {
pp::FileChooser_Dev file_chooser(instance(), PP_FILECHOOSERMODE_OPEN, "*");
ASSERT_FALSE(file_chooser.is_null());
TestCompletionCallbackWithOutput<std::vector<pp::FileRef>>
filechooser_callback(instance_->pp_instance(), callback_type());
filechooser_callback.WaitForResult(
file_chooser.Show(filechooser_callback.GetCallback()));
const std::vector<pp::FileRef>& output_ref = filechooser_callback.output();
ASSERT_EQ(0u, output_ref.size());
PASS();
}
std::string TestFileChooser::TestSaveAsSafeDefaultName() {
pp::FileChooser_Trusted file_chooser(instance(), PP_FILECHOOSERMODE_OPEN,
".txt", true ,
"innocuous.txt");
ASSERT_FALSE(file_chooser.is_null());
TestCompletionCallbackWithOutput<std::vector<pp::FileRef>>
filechooser_callback(instance_->pp_instance(), callback_type());
filechooser_callback.WaitForResult(
file_chooser.Show(filechooser_callback.GetCallback()));
const std::vector<pp::FileRef>& output_ref = filechooser_callback.output();
ASSERT_EQ(1u, output_ref.size());
ASSERT_TRUE(WriteDefaultContentsToFile(output_ref.front()));
PASS();
}
std::string TestFileChooser::TestSaveAsUnsafeDefaultName() {
pp::FileChooser_Trusted file_chooser(instance(), PP_FILECHOOSERMODE_OPEN,
"text/plain,.html", true ,
"unsafe.txt ");
ASSERT_FALSE(file_chooser.is_null());
TestCompletionCallbackWithOutput<std::vector<pp::FileRef>>
filechooser_callback(instance_->pp_instance(), callback_type());
filechooser_callback.WaitForResult(
file_chooser.Show(filechooser_callback.GetCallback()));
const std::vector<pp::FileRef>& output_ref = filechooser_callback.output();
ASSERT_EQ(1u, output_ref.size());
ASSERT_EQ("unsafe.txt_", output_ref.front().GetName().AsString());
ASSERT_TRUE(WriteDefaultContentsToFile(output_ref.front()));
PASS();
}
std::string TestFileChooser::TestSaveAsCancel() {
pp::FileChooser_Trusted file_chooser(instance(), PP_FILECHOOSERMODE_OPEN, "*",
true , "anything.txt");
ASSERT_FALSE(file_chooser.is_null());
TestCompletionCallbackWithOutput<std::vector<pp::FileRef>>
filechooser_callback(instance_->pp_instance(), callback_type());
filechooser_callback.WaitForResult(
file_chooser.Show(filechooser_callback.GetCallback()));
const std::vector<pp::FileRef>& output_ref = filechooser_callback.output();
ASSERT_EQ(0u, output_ref.size());
PASS();
}
std::string TestFileChooser::TestSaveAsDangerousExecutableAllowed() {
pp::FileChooser_Trusted file_chooser(instance(), PP_FILECHOOSERMODE_OPEN,
".exe", true ,
"dangerous.exe");
ASSERT_FALSE(file_chooser.is_null());
TestCompletionCallbackWithOutput<std::vector<pp::FileRef>>
filechooser_callback(instance_->pp_instance(), callback_type());
filechooser_callback.WaitForResult(
file_chooser.Show(filechooser_callback.GetCallback()));
const std::vector<pp::FileRef>& output_ref = filechooser_callback.output();
ASSERT_EQ(1u, output_ref.size());
ASSERT_EQ("dangerous.exe", output_ref.front().GetName().AsString());
ASSERT_TRUE(WriteDefaultContentsToFile(output_ref.front()));
PASS();
}
std::string TestFileChooser::TestSaveAsDangerousExecutableDisallowed() {
pp::FileChooser_Trusted file_chooser(instance(), PP_FILECHOOSERMODE_OPEN,
".exe", true ,
"dangerous.exe");
ASSERT_FALSE(file_chooser.is_null());
TestCompletionCallbackWithOutput<std::vector<pp::FileRef>>
filechooser_callback(instance_->pp_instance(), callback_type());
filechooser_callback.WaitForResult(
file_chooser.Show(filechooser_callback.GetCallback()));
const std::vector<pp::FileRef>& output_ref = filechooser_callback.output();
ASSERT_EQ(0u, output_ref.size());
PASS();
}
std::string TestFileChooser::TestSaveAsDangerousExtensionListDisallowed() {
pp::FileChooser_Trusted file_chooser(instance(), PP_FILECHOOSERMODE_OPEN,
".txt,.exe", true ,
"innocuous.txt");
ASSERT_FALSE(file_chooser.is_null());
TestCompletionCallbackWithOutput<std::vector<pp::FileRef>>
filechooser_callback(instance_->pp_instance(), callback_type());
filechooser_callback.WaitForResult(
file_chooser.Show(filechooser_callback.GetCallback()));
const std::vector<pp::FileRef>& output_ref = filechooser_callback.output();
ASSERT_EQ(0u, output_ref.size());
PASS();
}