summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortbarzic <tbarzic@chromium.org>2015-02-26 19:17:34 -0800
committerCommit bot <commit-bot@chromium.org>2015-02-27 03:19:05 +0000
commit089e28561693b3287409b96048d0c3c02cd0b740 (patch)
tree2bce2686e9fed63a3b521bb40e681f6d161c0ab2
parent715d4a3869c5fe16fa45a15a15e9583de4581527 (diff)
downloadchromium_src-089e28561693b3287409b96048d0c3c02cd0b740.zip
chromium_src-089e28561693b3287409b96048d0c3c02cd0b740.tar.gz
chromium_src-089e28561693b3287409b96048d0c3c02cd0b740.tar.bz2
Add tests for ExtensionPrinterHandler
In process, changed ExtensionPrinterHandler construction so pwg_raster_converter and task runner for reading converted PWG file can be injected through constructor. BUG=461114 TEST=unit_tests --gtest_filter=ExtensionPrinterHandler* Review URL: https://codereview.chromium.org/954283003 Cr-Commit-Position: refs/heads/master@{#318390}
-rw-r--r--chrome/browser/ui/webui/print_preview/extension_printer_handler.cc35
-rw-r--r--chrome/browser/ui/webui/print_preview/extension_printer_handler.h14
-rw-r--r--chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc771
-rw-r--r--chrome/browser/ui/webui/print_preview/printer_handler.cc5
-rw-r--r--chrome/chrome_tests_unit.gypi1
5 files changed, 809 insertions, 17 deletions
diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc b/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc
index aaeb3ff..e47a228 100644
--- a/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc
@@ -14,7 +14,6 @@
#include "base/memory/ref_counted.h"
#include "base/memory/ref_counted_memory.h"
#include "base/task_runner_util.h"
-#include "base/threading/worker_pool.h"
#include "chrome/browser/local_discovery/pwg_raster_converter.h"
#include "components/cloud_devices/common/cloud_device_description.h"
#include "components/cloud_devices/common/printer_description.h"
@@ -33,6 +32,7 @@ const char kContentTypePWGRaster[] = "image/pwg-raster";
const char kContentTypeAll[] = "*/*";
const char kInvalidDataPrintError[] = "INVALID_DATA";
+const char kInvalidTicketPrintError[] = "INVALID_TICKET";
// Reads raster data from file path |raster_path| and returns it as
// RefCountedMemory. Returns NULL on error.
@@ -57,6 +57,7 @@ scoped_refptr<base::RefCountedMemory> ReadConvertedPWGRasterFileOnWorkerThread(
// Posts a task to read a file containing converted PWG raster data to the
// worker pool.
void ReadConvertedPWGRasterFile(
+ const scoped_refptr<base::TaskRunner>& slow_task_runner,
const ExtensionPrinterHandler::RefCountedMemoryCallback& callback,
bool success,
const base::FilePath& pwg_file_path) {
@@ -66,7 +67,7 @@ void ReadConvertedPWGRasterFile(
}
base::PostTaskAndReplyWithResult(
- base::WorkerPool::GetTaskRunner(true).get(), FROM_HERE,
+ slow_task_runner.get(), FROM_HERE,
base::Bind(&ReadConvertedPWGRasterFileOnWorkerThread, pwg_file_path),
callback);
}
@@ -74,8 +75,11 @@ void ReadConvertedPWGRasterFile(
} // namespace
ExtensionPrinterHandler::ExtensionPrinterHandler(
- content::BrowserContext* browser_context)
- : browser_context_(browser_context), weak_ptr_factory_(this) {
+ content::BrowserContext* browser_context,
+ const scoped_refptr<base::TaskRunner>& slow_task_runner)
+ : browser_context_(browser_context),
+ slow_task_runner_(slow_task_runner),
+ weak_ptr_factory_(this) {
}
ExtensionPrinterHandler::~ExtensionPrinterHandler() {
@@ -134,25 +138,30 @@ void ExtensionPrinterHandler::StartPrint(
return;
}
+ cloud_devices::CloudDeviceDescription ticket;
+ if (!ticket.InitFromString(ticket_json)) {
+ WrapPrintCallback(callback, false, kInvalidTicketPrintError);
+ return;
+ }
+
print_job->content_type = kContentTypePWGRaster;
- ConvertToPWGRaster(print_data, printer_description, ticket_json, page_size,
+ ConvertToPWGRaster(print_data, printer_description, ticket, page_size,
base::Bind(&ExtensionPrinterHandler::DispatchPrintJob,
weak_ptr_factory_.GetWeakPtr(), callback,
base::Passed(&print_job)));
}
+void ExtensionPrinterHandler::SetPwgRasterConverterForTesting(
+ scoped_ptr<local_discovery::PWGRasterConverter> pwg_raster_converter) {
+ pwg_raster_converter_ = pwg_raster_converter.Pass();
+}
+
void ExtensionPrinterHandler::ConvertToPWGRaster(
const scoped_refptr<base::RefCountedMemory>& data,
const cloud_devices::CloudDeviceDescription& printer_description,
- const std::string& ticket_json,
+ const cloud_devices::CloudDeviceDescription& ticket,
const gfx::Size& page_size,
const ExtensionPrinterHandler::RefCountedMemoryCallback& callback) {
- cloud_devices::CloudDeviceDescription ticket;
- if (!ticket.InitFromString(ticket_json)) {
- callback.Run(scoped_refptr<base::RefCountedMemory>());
- return;
- }
-
if (!pwg_raster_converter_) {
pwg_raster_converter_ = PWGRasterConverter::CreateDefault();
}
@@ -160,7 +169,7 @@ void ExtensionPrinterHandler::ConvertToPWGRaster(
data.get(),
PWGRasterConverter::GetConversionSettings(printer_description, page_size),
PWGRasterConverter::GetBitmapSettings(printer_description, ticket),
- base::Bind(&ReadConvertedPWGRasterFile, callback));
+ base::Bind(&ReadConvertedPWGRasterFile, slow_task_runner_, callback));
}
void ExtensionPrinterHandler::DispatchPrintJob(
diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler.h b/chrome/browser/ui/webui/print_preview/extension_printer_handler.h
index 89238e2..408c4bc 100644
--- a/chrome/browser/ui/webui/print_preview/extension_printer_handler.h
+++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler.h
@@ -17,6 +17,7 @@ namespace base {
class DictionaryValue;
class ListValue;
class RefCountedMemory;
+class TaskRunner;
}
namespace content {
@@ -42,7 +43,9 @@ class ExtensionPrinterHandler : public PrinterHandler {
using RefCountedMemoryCallback =
base::Callback<void(const scoped_refptr<base::RefCountedMemory>&)>;
- explicit ExtensionPrinterHandler(content::BrowserContext* browser_context);
+ ExtensionPrinterHandler(
+ content::BrowserContext* browser_context,
+ const scoped_refptr<base::TaskRunner>& slow_task_runner);
~ExtensionPrinterHandler() override;
@@ -62,13 +65,18 @@ class ExtensionPrinterHandler : public PrinterHandler {
const PrinterHandler::PrintCallback& callback) override;
private:
+ friend class ExtensionPrinterHandlerTest;
+
+ void SetPwgRasterConverterForTesting(
+ scoped_ptr<local_discovery::PWGRasterConverter> pwg_raster_converter);
+
// Converts |data| to PWG raster format (from PDF) for a printer described
// by |printer_description|.
// |callback| is called with the converted data.
void ConvertToPWGRaster(
const scoped_refptr<base::RefCountedMemory>& data,
const cloud_devices::CloudDeviceDescription& printer_description,
- const std::string& ticket,
+ const cloud_devices::CloudDeviceDescription& ticket,
const gfx::Size& page_size,
const RefCountedMemoryCallback& callback);
@@ -97,6 +105,8 @@ class ExtensionPrinterHandler : public PrinterHandler {
scoped_ptr<local_discovery::PWGRasterConverter> pwg_raster_converter_;
+ scoped_refptr<base::TaskRunner> slow_task_runner_;
+
base::WeakPtrFactory<ExtensionPrinterHandler> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ExtensionPrinterHandler);
diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc
new file mode 100644
index 0000000..7fb2c96
--- /dev/null
+++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc
@@ -0,0 +1,771 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/json/json_string_value_serializer.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/run_loop.h"
+#include "base/values.h"
+#include "chrome/browser/local_discovery/pwg_raster_converter.h"
+#include "chrome/browser/ui/webui/print_preview/extension_printer_handler.h"
+#include "chrome/test/base/testing_profile.h"
+#include "extensions/browser/api/printer_provider/printer_provider_api.h"
+#include "extensions/browser/api/printer_provider/printer_provider_api_factory.h"
+#include "extensions/browser/api/printer_provider/printer_provider_print_job.h"
+#include "printing/pdf_render_settings.h"
+#include "printing/pwg_raster_settings.h"
+#include "printing/units.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/geometry/size.h"
+
+using extensions::PrinterProviderAPI;
+using extensions::PrinterProviderPrintJob;
+using local_discovery::PWGRasterConverter;
+
+namespace {
+
+// Printer id used for requests in tests.
+const char kPrinterId[] = "printer_id";
+
+// Printer list used a result for getPrinters.
+const char kPrinterDescriptionList[] =
+ "[{"
+ " \"id\": \"printer1\","
+ " \"name\": \"Printer 1\""
+ "}, {"
+ " \"id\": \"printer2\","
+ " \"name\": \"Printer 2\","
+ " \"description\": \"Test printer 2\""
+ "}]";
+
+// Printer capability for printer that supports all content types.
+const char kAllContentTypesSupportedPrinter[] =
+ "{"
+ " \"version\": \"1.0\","
+ " \"printer\": {"
+ " \"supported_content_type\": ["
+ " {\"content_type\": \"*/*\"}"
+ " ]"
+ " }"
+ "}";
+
+// Printer capability for a printer that supports PDF.
+const char kPdfSupportedPrinter[] =
+ "{"
+ " \"version\": \"1.0\","
+ " \"printer\": {"
+ " \"supported_content_type\": ["
+ " {\"content_type\": \"application/pdf\"},"
+ " {\"content_type\": \"image/pwg-raster\"}"
+ " ]"
+ " }"
+ "}";
+
+// Printer capability for a printer that supportd only PWG raster.
+const char kPWGRasterOnlyPrinterSimpleDescription[] =
+ "{"
+ " \"version\": \"1.0\","
+ " \"printer\": {"
+ " \"supported_content_type\": ["
+ " {\"content_type\": \"image/pwg-raster\"}"
+ " ]"
+ " }"
+ "}";
+
+// Printer capability for a printer that supportd only PWG raster that has
+// options other that supported_content_type set.
+const char kPWGRasterOnlyPrinter[] =
+ "{"
+ " \"version\": \"1.0\","
+ " \"printer\": {"
+ " \"supported_content_type\": ["
+ " {\"content_type\": \"image/pwg-raster\"}"
+ " ],"
+ " \"pwg_raster_config\": {"
+ " \"document_sheet_back\": \"FLIPPED\","
+ " \"reverse_order_streaming\": true,"
+ " \"rotate_all_pages\": true"
+ " },"
+ " \"dpi\": {"
+ " \"option\": [{"
+ " \"horizontal_dpi\": 100,"
+ " \"vertical_dpi\": 200,"
+ " \"is_default\": true"
+ " }]"
+ " }"
+ " }"
+ "}";
+
+// Print ticket with no parameters set.
+const char kEmptyPrintTicket[] = "{\"version\": \"1.0\"}";
+
+// Print ticket that has duplex parameter set.
+const char kPrintTicketWithDuplex[] =
+ "{"
+ " \"version\": \"1.0\","
+ " \"print\": {"
+ " \"duplex\": {\"type\": \"LONG_EDGE\"}"
+ " }"
+ "}";
+
+// Suffix appended to document data by fake PWGRasterConverter.
+const char kPWGConversionSuffix[] = "_converted";
+
+const char kContentTypePDF[] = "application/pdf";
+const char kContentTypePWG[] = "image/pwg-raster";
+
+// Print request status considered to be successful by fake PrinterProviderAPI.
+const char kPrintRequestSuccess[] = "OK";
+
+// Used as a callback to StartGetPrinters in tests.
+// Increases |*call_count| and records values returned by StartGetPrinters.
+void RecordPrinterList(size_t* call_count,
+ scoped_ptr<base::ListValue>* printers_out,
+ bool* is_done_out,
+ const base::ListValue& printers,
+ bool is_done) {
+ ++(*call_count);
+ printers_out->reset(printers.DeepCopy());
+ *is_done_out = is_done;
+}
+
+// Used as a callback to StartGetCapability in tests.
+// Increases |*call_count| and records values returned by StartGetCapability.
+void RecordCapability(size_t* call_count,
+ std::string* destination_id_out,
+ scoped_ptr<base::DictionaryValue>* capability_out,
+ const std::string& destination_id,
+ const base::DictionaryValue& capability) {
+ ++(*call_count);
+ *destination_id_out = destination_id;
+ capability_out->reset(capability.DeepCopy());
+}
+
+// Used as a callback to StartPrint in tests.
+// Increases |*call_count| and records values returned by StartPrint.
+void RecordPrintResult(size_t* call_count,
+ bool* success_out,
+ std::string* status_out,
+ bool success,
+ const std::string& status) {
+ ++(*call_count);
+ *success_out = success;
+ *status_out = status;
+}
+
+// Converts JSON string to base::ListValue object.
+// On failure, returns NULL and fills |*error| string.
+scoped_ptr<base::ListValue> GetJSONAsListValue(const std::string& json,
+ std::string* error) {
+ scoped_ptr<base::Value> deserialized(
+ JSONStringValueSerializer(json).Deserialize(NULL, error));
+ if (!deserialized)
+ return scoped_ptr<base::ListValue>();
+ base::ListValue* list = nullptr;
+ if (!deserialized->GetAsList(&list)) {
+ *error = "Value is not a list.";
+ return scoped_ptr<base::ListValue>();
+ }
+ return scoped_ptr<base::ListValue>(list->DeepCopy());
+}
+
+// Converts JSON string to base::DictionaryValue object.
+// On failure, returns NULL and fills |*error| string.
+scoped_ptr<base::DictionaryValue> GetJSONAsDictionaryValue(
+ const std::string& json,
+ std::string* error) {
+ scoped_ptr<base::Value> deserialized(
+ JSONStringValueSerializer(json).Deserialize(NULL, error));
+ if (!deserialized)
+ return scoped_ptr<base::DictionaryValue>();
+ base::DictionaryValue* dictionary;
+ if (!deserialized->GetAsDictionary(&dictionary)) {
+ *error = "Value is not a dictionary.";
+ return scoped_ptr<base::DictionaryValue>();
+ }
+ return scoped_ptr<base::DictionaryValue>(dictionary->DeepCopy());
+}
+
+// Fake PWGRasterconverter used in the tests.
+class FakePWGRasterConverter : public PWGRasterConverter {
+ public:
+ FakePWGRasterConverter() : fail_conversion_(false), initialized_(false) {}
+ ~FakePWGRasterConverter() override = default;
+
+ // PWGRasterConverter implementation.
+ // It writes |data| to a temp file, appending it |kPWGConversionSuffix|.
+ // Also, remembers conversion and bitmap settings passed into the method.
+ void Start(base::RefCountedMemory* data,
+ const printing::PdfRenderSettings& conversion_settings,
+ const printing::PwgRasterSettings& bitmap_settings,
+ const ResultCallback& callback) override {
+ if (fail_conversion_) {
+ callback.Run(false, base::FilePath());
+ return;
+ }
+
+ if (!initialized_ && !temp_dir_.CreateUniqueTempDir()) {
+ ADD_FAILURE() << "Unable to create target dir for cenverter";
+ callback.Run(false, base::FilePath());
+ return;
+ }
+
+ initialized_ = true;
+
+ std::string data_str(data->front_as<char>(), data->size());
+ data_str.append(kPWGConversionSuffix);
+ base::FilePath target_path = temp_dir_.path().AppendASCII("output.pwg");
+ int written = WriteFile(target_path, data_str.c_str(), data_str.size());
+ if (written != static_cast<int>(data_str.size())) {
+ ADD_FAILURE() << "Failed to write pwg raster file.";
+ callback.Run(false, base::FilePath());
+ return;
+ }
+
+ conversion_settings_ = conversion_settings;
+ bitmap_settings_ = bitmap_settings;
+
+ callback.Run(true, target_path);
+ }
+
+ // Makes |Start| method always return an error.
+ void FailConversion() { fail_conversion_ = true; }
+
+ const printing::PdfRenderSettings& conversion_settings() const {
+ return conversion_settings_;
+ }
+
+ const printing::PwgRasterSettings& bitmap_settings() const {
+ return bitmap_settings_;
+ }
+
+ private:
+ base::ScopedTempDir temp_dir_;
+
+ printing::PdfRenderSettings conversion_settings_;
+ printing::PwgRasterSettings bitmap_settings_;
+ bool fail_conversion_;
+ bool initialized_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakePWGRasterConverter);
+};
+
+// Copy of data contained in print job passed to |DispatchPrintRequested|.
+struct PrintJobParams {
+ std::string printer_id;
+ std::string ticket;
+ std::string content_type;
+ std::string document;
+};
+
+// Information about received print requests.
+struct PrintRequestInfo {
+ PrinterProviderAPI::PrintCallback callback;
+ PrintJobParams params;
+};
+
+// Fake PrinterProviderAPI used in tests.
+// It caches requests issued to API and exposes methods to trigger their
+// callbacks.
+class FakePrinterProviderAPI : public PrinterProviderAPI {
+ public:
+ FakePrinterProviderAPI() = default;
+ ~FakePrinterProviderAPI() override = default;
+
+ void DispatchGetPrintersRequested(
+ const PrinterProviderAPI::GetPrintersCallback& callback) override {
+ pending_printers_callbacks_.push_back(callback);
+ }
+
+ void DispatchGetCapabilityRequested(
+ const std::string& destination_id,
+ const PrinterProviderAPI::GetCapabilityCallback& callback) override {
+ pending_capability_callbacks_.push_back(base::Bind(callback));
+ }
+
+ void DispatchPrintRequested(
+ const PrinterProviderPrintJob& job,
+ const PrinterProviderAPI::PrintCallback& callback) override {
+ PrintRequestInfo request_info;
+ request_info.callback = callback;
+
+ request_info.params.printer_id = job.printer_id;
+ request_info.params.ticket = job.ticket_json;
+ request_info.params.content_type = job.content_type;
+ request_info.params.document = std::string(
+ job.document_bytes->front_as<char>(), job.document_bytes->size());
+
+ pending_print_requests_.push_back(request_info);
+ }
+
+ size_t pending_get_printers_count() const {
+ return pending_printers_callbacks_.size();
+ }
+
+ void TriggerNextGetPrintersCallback(const base::ListValue& printers,
+ bool done) {
+ ASSERT_GT(pending_get_printers_count(), 0u);
+ pending_printers_callbacks_[0].Run(printers, done);
+ pending_printers_callbacks_.erase(pending_printers_callbacks_.begin());
+ }
+
+ size_t pending_get_capability_count() const {
+ return pending_capability_callbacks_.size();
+ }
+
+ void TriggerNextGetCapabilityCallback(
+ const base::DictionaryValue& description) {
+ ASSERT_GT(pending_get_capability_count(), 0u);
+ pending_capability_callbacks_[0].Run(description);
+ pending_capability_callbacks_.erase(pending_capability_callbacks_.begin());
+ }
+
+ size_t pending_print_count() const { return pending_print_requests_.size(); }
+
+ const PrintJobParams* GetNextPendingPrintJob() const {
+ EXPECT_GT(pending_print_count(), 0u);
+ if (pending_print_count() == 0)
+ return NULL;
+ return &pending_print_requests_[0].params;
+ }
+
+ void TriggerNextPrintCallback(const std::string& result) {
+ ASSERT_GT(pending_print_count(), 0u);
+ pending_print_requests_[0].callback.Run(result == kPrintRequestSuccess,
+ result);
+ pending_print_requests_.erase(pending_print_requests_.begin());
+ }
+
+ private:
+ std::vector<PrinterProviderAPI::GetPrintersCallback>
+ pending_printers_callbacks_;
+ std::vector<PrinterProviderAPI::GetCapabilityCallback>
+ pending_capability_callbacks_;
+ std::vector<PrintRequestInfo> pending_print_requests_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakePrinterProviderAPI);
+};
+
+KeyedService* BuildTestingPrinterProviderAPI(content::BrowserContext* context) {
+ return new FakePrinterProviderAPI();
+}
+
+} // namespace
+
+class ExtensionPrinterHandlerTest : public testing::Test {
+ public:
+ ExtensionPrinterHandlerTest() : pwg_raster_converter_(NULL) {}
+ ~ExtensionPrinterHandlerTest() override = default;
+
+ void SetUp() override {
+ TestingProfile::Builder profile_builder;
+ profile_builder.AddTestingFactory(
+ extensions::PrinterProviderAPIFactory::GetInstance(),
+ &BuildTestingPrinterProviderAPI);
+ profile_ = profile_builder.Build();
+
+ extension_printer_handler_.reset(new ExtensionPrinterHandler(
+ profile_.get(), message_loop_.task_runner()));
+
+ pwg_raster_converter_ = new FakePWGRasterConverter();
+ extension_printer_handler_->SetPwgRasterConverterForTesting(
+ scoped_ptr<PWGRasterConverter>(pwg_raster_converter_));
+ }
+
+ protected:
+ FakePrinterProviderAPI* GetPrinterProviderAPI() {
+ return static_cast<FakePrinterProviderAPI*>(
+ extensions::PrinterProviderAPIFactory::GetInstance()
+ ->GetForBrowserContext(profile_.get()));
+ }
+
+ scoped_ptr<ExtensionPrinterHandler> extension_printer_handler_;
+
+ FakePWGRasterConverter* pwg_raster_converter_;
+
+ private:
+ base::MessageLoop message_loop_;
+
+ scoped_ptr<TestingProfile> profile_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionPrinterHandlerTest);
+};
+
+TEST_F(ExtensionPrinterHandlerTest, GetPrinters) {
+ size_t call_count = 0;
+ scoped_ptr<base::ListValue> printers;
+ bool is_done = false;
+
+ extension_printer_handler_->StartGetPrinters(
+ base::Bind(&RecordPrinterList, &call_count, &printers, &is_done));
+
+ EXPECT_FALSE(printers.get());
+ FakePrinterProviderAPI* fake_api = GetPrinterProviderAPI();
+ ASSERT_TRUE(fake_api);
+ ASSERT_EQ(1u, fake_api->pending_get_printers_count());
+
+ std::string error;
+ scoped_ptr<base::ListValue> original_printers(
+ GetJSONAsListValue(kPrinterDescriptionList, &error));
+ ASSERT_TRUE(original_printers) << "Failed to deserialize printers: " << error;
+
+ fake_api->TriggerNextGetPrintersCallback(*original_printers, true);
+
+ EXPECT_EQ(1u, call_count);
+ EXPECT_TRUE(is_done);
+ ASSERT_TRUE(printers.get());
+ EXPECT_TRUE(printers->Equals(original_printers.get()))
+ << *printers << ", expected: " << *original_printers;
+}
+
+TEST_F(ExtensionPrinterHandlerTest, GetPrinters_Reset) {
+ size_t call_count = 0;
+ scoped_ptr<base::ListValue> printers;
+ bool is_done = false;
+
+ extension_printer_handler_->StartGetPrinters(
+ base::Bind(&RecordPrinterList, &call_count, &printers, &is_done));
+
+ EXPECT_FALSE(printers.get());
+ FakePrinterProviderAPI* fake_api = GetPrinterProviderAPI();
+ ASSERT_TRUE(fake_api);
+ ASSERT_EQ(1u, fake_api->pending_get_printers_count());
+
+ extension_printer_handler_->Reset();
+
+ std::string error;
+ scoped_ptr<base::ListValue> original_printers(
+ GetJSONAsListValue(kPrinterDescriptionList, &error));
+ ASSERT_TRUE(original_printers) << "Error deserializing printers: " << error;
+
+ fake_api->TriggerNextGetPrintersCallback(*original_printers, true);
+
+ EXPECT_EQ(0u, call_count);
+}
+
+TEST_F(ExtensionPrinterHandlerTest, GetCapability) {
+ size_t call_count = 0;
+ std::string destination_id;
+ scoped_ptr<base::DictionaryValue> capability;
+
+ extension_printer_handler_->StartGetCapability(
+ kPrinterId,
+ base::Bind(&RecordCapability, &call_count, &destination_id, &capability));
+
+ EXPECT_EQ(0u, call_count);
+
+ FakePrinterProviderAPI* fake_api = GetPrinterProviderAPI();
+ ASSERT_TRUE(fake_api);
+ ASSERT_EQ(1u, fake_api->pending_get_capability_count());
+
+ std::string error;
+ scoped_ptr<base::DictionaryValue> original_capability(
+ GetJSONAsDictionaryValue(kPWGRasterOnlyPrinterSimpleDescription, &error));
+ ASSERT_TRUE(original_capability)
+ << "Error deserializing capability: " << error;
+
+ fake_api->TriggerNextGetCapabilityCallback(*original_capability);
+
+ EXPECT_EQ(1u, call_count);
+ EXPECT_EQ(kPrinterId, destination_id);
+ ASSERT_TRUE(capability.get());
+ EXPECT_TRUE(capability->Equals(original_capability.get()))
+ << *capability << ", expected: " << *original_capability;
+}
+
+TEST_F(ExtensionPrinterHandlerTest, GetCapability_Reset) {
+ size_t call_count = 0;
+ std::string destination_id;
+ scoped_ptr<base::DictionaryValue> capability;
+
+ extension_printer_handler_->StartGetCapability(
+ kPrinterId,
+ base::Bind(&RecordCapability, &call_count, &destination_id, &capability));
+
+ EXPECT_EQ(0u, call_count);
+
+ FakePrinterProviderAPI* fake_api = GetPrinterProviderAPI();
+ ASSERT_TRUE(fake_api);
+ ASSERT_EQ(1u, fake_api->pending_get_capability_count());
+
+ extension_printer_handler_->Reset();
+
+ std::string error;
+ scoped_ptr<base::DictionaryValue> original_capability(
+ GetJSONAsDictionaryValue(kPWGRasterOnlyPrinterSimpleDescription, &error));
+ ASSERT_TRUE(original_capability)
+ << "Error deserializing capability: " << error;
+
+ fake_api->TriggerNextGetCapabilityCallback(*original_capability);
+
+ EXPECT_EQ(0u, call_count);
+}
+
+TEST_F(ExtensionPrinterHandlerTest, Print_Pdf) {
+ size_t call_count = 0;
+ bool success = false;
+ std::string status;
+
+ scoped_refptr<base::RefCountedString> print_data(
+ new base::RefCountedString());
+ print_data->data() = "print data, PDF";
+
+ extension_printer_handler_->StartPrint(
+ kPrinterId, kPdfSupportedPrinter, kEmptyPrintTicket, gfx::Size(100, 100),
+ print_data,
+ base::Bind(&RecordPrintResult, &call_count, &success, &status));
+
+ EXPECT_EQ(0u, call_count);
+ FakePrinterProviderAPI* fake_api = GetPrinterProviderAPI();
+ ASSERT_TRUE(fake_api);
+ ASSERT_EQ(1u, fake_api->pending_print_count());
+
+ const PrintJobParams* print_job = fake_api->GetNextPendingPrintJob();
+ ASSERT_TRUE(print_job);
+
+ EXPECT_EQ(kPrinterId, print_job->printer_id);
+ EXPECT_EQ(kEmptyPrintTicket, print_job->ticket);
+ EXPECT_EQ(kContentTypePDF, print_job->content_type);
+ EXPECT_EQ(print_data->data(), print_job->document);
+
+ fake_api->TriggerNextPrintCallback(kPrintRequestSuccess);
+
+ EXPECT_EQ(1u, call_count);
+ EXPECT_TRUE(success);
+ EXPECT_EQ(kPrintRequestSuccess, status);
+}
+
+TEST_F(ExtensionPrinterHandlerTest, Print_Pdf_Reset) {
+ size_t call_count = 0;
+ bool success = false;
+ std::string status;
+
+ scoped_refptr<base::RefCountedString> print_data(
+ new base::RefCountedString());
+ print_data->data() = "print data, PDF";
+
+ extension_printer_handler_->StartPrint(
+ kPrinterId, kPdfSupportedPrinter, kEmptyPrintTicket, gfx::Size(100, 100),
+ print_data,
+ base::Bind(&RecordPrintResult, &call_count, &success, &status));
+
+ EXPECT_EQ(0u, call_count);
+ FakePrinterProviderAPI* fake_api = GetPrinterProviderAPI();
+ ASSERT_TRUE(fake_api);
+ ASSERT_EQ(1u, fake_api->pending_print_count());
+
+ extension_printer_handler_->Reset();
+
+ fake_api->TriggerNextPrintCallback(kPrintRequestSuccess);
+
+ EXPECT_EQ(0u, call_count);
+}
+
+TEST_F(ExtensionPrinterHandlerTest, Print_All) {
+ size_t call_count = 0;
+ bool success = false;
+ std::string status;
+
+ scoped_refptr<base::RefCountedString> print_data(
+ new base::RefCountedString());
+ print_data->data() = "print data, PDF";
+
+ extension_printer_handler_->StartPrint(
+ kPrinterId, kAllContentTypesSupportedPrinter, kEmptyPrintTicket,
+ gfx::Size(100, 100), print_data,
+ base::Bind(&RecordPrintResult, &call_count, &success, &status));
+
+ EXPECT_EQ(0u, call_count);
+
+ FakePrinterProviderAPI* fake_api = GetPrinterProviderAPI();
+ ASSERT_TRUE(fake_api);
+ ASSERT_EQ(1u, fake_api->pending_print_count());
+
+ const PrintJobParams* print_job = fake_api->GetNextPendingPrintJob();
+ ASSERT_TRUE(print_job);
+
+ EXPECT_EQ(kPrinterId, print_job->printer_id);
+ EXPECT_EQ(kEmptyPrintTicket, print_job->ticket);
+ EXPECT_EQ(kContentTypePDF, print_job->content_type);
+ EXPECT_EQ(print_data->data(), print_job->document);
+
+ fake_api->TriggerNextPrintCallback(kPrintRequestSuccess);
+
+ EXPECT_EQ(1u, call_count);
+ EXPECT_TRUE(success);
+ EXPECT_EQ(kPrintRequestSuccess, status);
+}
+
+TEST_F(ExtensionPrinterHandlerTest, Print_Pwg) {
+ size_t call_count = 0;
+ bool success = false;
+ std::string status;
+
+ scoped_refptr<base::RefCountedString> print_data(
+ new base::RefCountedString());
+ print_data->data() = "print data, PDF";
+
+ extension_printer_handler_->StartPrint(
+ kPrinterId, kPWGRasterOnlyPrinterSimpleDescription, kEmptyPrintTicket,
+ gfx::Size(100, 50), print_data,
+ base::Bind(&RecordPrintResult, &call_count, &success, &status));
+
+ EXPECT_EQ(0u, call_count);
+
+ base::RunLoop().RunUntilIdle();
+
+ FakePrinterProviderAPI* fake_api = GetPrinterProviderAPI();
+ ASSERT_TRUE(fake_api);
+ ASSERT_EQ(1u, fake_api->pending_print_count());
+
+ EXPECT_EQ(printing::TRANSFORM_NORMAL,
+ pwg_raster_converter_->bitmap_settings().odd_page_transform);
+ EXPECT_FALSE(pwg_raster_converter_->bitmap_settings().rotate_all_pages);
+ EXPECT_FALSE(pwg_raster_converter_->bitmap_settings().reverse_page_order);
+
+ EXPECT_EQ(printing::kDefaultPdfDpi,
+ pwg_raster_converter_->conversion_settings().dpi());
+ EXPECT_TRUE(pwg_raster_converter_->conversion_settings().autorotate());
+ EXPECT_EQ("0,0 208x416", // vertically_oriented_size * dpi / points_per_inch
+ pwg_raster_converter_->conversion_settings().area().ToString());
+
+ const PrintJobParams* print_job = fake_api->GetNextPendingPrintJob();
+ ASSERT_TRUE(print_job);
+
+ EXPECT_EQ(kPrinterId, print_job->printer_id);
+ EXPECT_EQ(kEmptyPrintTicket, print_job->ticket);
+ EXPECT_EQ(kContentTypePWG, print_job->content_type);
+ EXPECT_EQ(print_data->data() + kPWGConversionSuffix, print_job->document);
+
+ fake_api->TriggerNextPrintCallback(kPrintRequestSuccess);
+
+ EXPECT_EQ(1u, call_count);
+ EXPECT_TRUE(success);
+ EXPECT_EQ(kPrintRequestSuccess, status);
+}
+
+TEST_F(ExtensionPrinterHandlerTest, Print_Pwg_NonDefaultSettings) {
+ size_t call_count = 0;
+ bool success = false;
+ std::string status;
+
+ scoped_refptr<base::RefCountedString> print_data(
+ new base::RefCountedString());
+ print_data->data() = "print data, PDF";
+
+ extension_printer_handler_->StartPrint(
+ kPrinterId, kPWGRasterOnlyPrinter, kPrintTicketWithDuplex,
+ gfx::Size(100, 50), print_data,
+ base::Bind(&RecordPrintResult, &call_count, &success, &status));
+
+ EXPECT_EQ(0u, call_count);
+
+ base::RunLoop().RunUntilIdle();
+
+ FakePrinterProviderAPI* fake_api = GetPrinterProviderAPI();
+ ASSERT_TRUE(fake_api);
+ ASSERT_EQ(1u, fake_api->pending_print_count());
+
+ EXPECT_EQ(printing::TRANSFORM_FLIP_VERTICAL,
+ pwg_raster_converter_->bitmap_settings().odd_page_transform);
+ EXPECT_TRUE(pwg_raster_converter_->bitmap_settings().rotate_all_pages);
+ EXPECT_TRUE(pwg_raster_converter_->bitmap_settings().reverse_page_order);
+
+ EXPECT_EQ(200, // max(vertical_dpi, horizontal_dpi)
+ pwg_raster_converter_->conversion_settings().dpi());
+ EXPECT_TRUE(pwg_raster_converter_->conversion_settings().autorotate());
+ EXPECT_EQ("0,0 138x277", // vertically_oriented_size * dpi / points_per_inch
+ pwg_raster_converter_->conversion_settings().area().ToString());
+
+ const PrintJobParams* print_job = fake_api->GetNextPendingPrintJob();
+ ASSERT_TRUE(print_job);
+
+ EXPECT_EQ(kPrinterId, print_job->printer_id);
+ EXPECT_EQ(kPrintTicketWithDuplex, print_job->ticket);
+ EXPECT_EQ(kContentTypePWG, print_job->content_type);
+ EXPECT_EQ(print_data->data() + kPWGConversionSuffix, print_job->document);
+
+ fake_api->TriggerNextPrintCallback(kPrintRequestSuccess);
+
+ EXPECT_EQ(1u, call_count);
+ EXPECT_TRUE(success);
+ EXPECT_EQ(kPrintRequestSuccess, status);
+}
+
+TEST_F(ExtensionPrinterHandlerTest, Print_Pwg_Reset) {
+ size_t call_count = 0;
+ bool success = false;
+ std::string status;
+
+ scoped_refptr<base::RefCountedString> print_data(
+ new base::RefCountedString());
+ print_data->data() = "print data, PDF";
+
+ extension_printer_handler_->StartPrint(
+ kPrinterId, kPWGRasterOnlyPrinterSimpleDescription, kEmptyPrintTicket,
+ gfx::Size(100, 50), print_data,
+ base::Bind(&RecordPrintResult, &call_count, &success, &status));
+
+ EXPECT_EQ(0u, call_count);
+
+ base::RunLoop().RunUntilIdle();
+
+ FakePrinterProviderAPI* fake_api = GetPrinterProviderAPI();
+ ASSERT_TRUE(fake_api);
+ ASSERT_EQ(1u, fake_api->pending_print_count());
+
+ extension_printer_handler_->Reset();
+
+ fake_api->TriggerNextPrintCallback(kPrintRequestSuccess);
+
+ EXPECT_EQ(0u, call_count);
+}
+
+TEST_F(ExtensionPrinterHandlerTest, Print_Pwg_InvalidTicket) {
+ size_t call_count = 0;
+ bool success = false;
+ std::string status;
+
+ scoped_refptr<base::RefCountedString> print_data(
+ new base::RefCountedString());
+ print_data->data() = "print data, PDF";
+
+ extension_printer_handler_->StartPrint(
+ kPrinterId, kPWGRasterOnlyPrinterSimpleDescription, "{}" /* ticket */,
+ gfx::Size(100, 100), print_data,
+ base::Bind(&RecordPrintResult, &call_count, &success, &status));
+
+ EXPECT_EQ(1u, call_count);
+
+ EXPECT_FALSE(success);
+ EXPECT_EQ("INVALID_TICKET", status);
+}
+
+TEST_F(ExtensionPrinterHandlerTest, Print_Pwg_FailedConversion) {
+ size_t call_count = 0;
+ bool success = false;
+ std::string status;
+
+ pwg_raster_converter_->FailConversion();
+
+ scoped_refptr<base::RefCountedString> print_data(
+ new base::RefCountedString());
+ print_data->data() = "print data, PDF";
+
+ extension_printer_handler_->StartPrint(
+ kPrinterId, kPWGRasterOnlyPrinterSimpleDescription, kEmptyPrintTicket,
+ gfx::Size(100, 100), print_data,
+ base::Bind(&RecordPrintResult, &call_count, &success, &status));
+
+ EXPECT_EQ(1u, call_count);
+
+ EXPECT_FALSE(success);
+ EXPECT_EQ("INVALID_DATA", status);
+}
diff --git a/chrome/browser/ui/webui/print_preview/printer_handler.cc b/chrome/browser/ui/webui/print_preview/printer_handler.cc
index a38f46b..edc85d1 100644
--- a/chrome/browser/ui/webui/print_preview/printer_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/printer_handler.cc
@@ -4,11 +4,12 @@
#include "chrome/browser/ui/webui/print_preview/printer_handler.h"
+#include "base/threading/worker_pool.h"
#include "chrome/browser/ui/webui/print_preview/extension_printer_handler.h"
// static
scoped_ptr<PrinterHandler> PrinterHandler::CreateForExtensionPrinters(
content::BrowserContext* browser_context) {
- return scoped_ptr<ExtensionPrinterHandler>(
- new ExtensionPrinterHandler(browser_context));
+ return scoped_ptr<ExtensionPrinterHandler>(new ExtensionPrinterHandler(
+ browser_context, base::WorkerPool::GetTaskRunner(true)));
}
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index 5f96c31..4df53f5 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -1073,6 +1073,7 @@
'browser/printing/print_preview_dialog_controller_unittest.cc',
'browser/printing/print_preview_test.cc',
'browser/printing/print_preview_test.h',
+ 'browser/ui/webui/print_preview/extension_printer_handler_unittest.cc',
'browser/ui/webui/print_preview/print_preview_ui_unittest.cc',
'common/service_process_util_unittest.cc',
'service/cloud_print/cloud_print_service_helpers_unittest.cc',