• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/printing/print_dialog_cloud.h"
6 #include "chrome/browser/printing/print_dialog_cloud_internal.h"
7 
8 #include <string>
9 #include <vector>
10 
11 #include "base/file_path.h"
12 #include "base/file_util.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/path_service.h"
15 #include "base/string_util.h"
16 #include "base/utf_string_conversions.h"
17 #include "base/values.h"
18 #include "chrome/browser/printing/cloud_print/cloud_print_url.h"
19 #include "chrome/common/chrome_paths.h"
20 #include "chrome/common/url_constants.h"
21 #include "chrome/test/testing_profile.h"
22 #include "content/browser/browser_thread.h"
23 #include "content/common/notification_details.h"
24 #include "content/common/notification_source.h"
25 #include "content/common/notification_type.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 
29 using testing::A;
30 using testing::AtLeast;
31 using testing::Eq;
32 using testing::HasSubstr;
33 using testing::IsNull;
34 using testing::NotNull;
35 using testing::Return;
36 using testing::StrEq;
37 using testing::_;
38 
39 static const char* const kPDFTestFile = "printing/cloud_print_unittest.pdf";
40 static const char* const kEmptyPDFTestFile =
41     "printing/cloud_print_emptytest.pdf";
42 static const char* const kMockJobTitle = "Mock Job Title";
43 
GetTestDataFileName()44 FilePath GetTestDataFileName() {
45   FilePath test_data_directory;
46   PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory);
47   FilePath test_file = test_data_directory.AppendASCII(kPDFTestFile);
48   return test_file;
49 }
50 
GetEmptyDataFileName()51 FilePath GetEmptyDataFileName() {
52   FilePath test_data_directory;
53   PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory);
54   FilePath test_file = test_data_directory.AppendASCII(kEmptyPDFTestFile);
55   return test_file;
56 }
57 
GetTestData()58 char* GetTestData() {
59   static std::string sTestFileData;
60   if (sTestFileData.empty()) {
61     FilePath test_file = GetTestDataFileName();
62     file_util::ReadFileToString(test_file, &sTestFileData);
63   }
64   return &sTestFileData[0];
65 }
66 
67 MATCHER_P(StringValueEq, expected, "StringValue") {
68   if (expected->Equals(&arg))
69     return true;
70   std::string expected_string, arg_string;
71   expected->GetAsString(&expected_string);
72   arg.GetAsString(&arg_string);
73   *result_listener << "'" << arg_string
74                    << "' (expected '" << expected_string << "')";
75   return false;
76 }
77 
78 namespace internal_cloud_print_helpers {
79 
80 class MockCloudPrintFlowHandler
81     : public CloudPrintFlowHandler,
82       public base::SupportsWeakPtr<MockCloudPrintFlowHandler> {
83  public:
MockCloudPrintFlowHandler(const FilePath & path,const string16 & title,const std::string & file_type)84   explicit MockCloudPrintFlowHandler(const FilePath& path,
85                                      const string16& title,
86                                      const std::string& file_type)
87       : CloudPrintFlowHandler(path, title, file_type) {}
88   MOCK_METHOD0(DestructorCalled, void());
89   MOCK_METHOD0(RegisterMessages, void());
90   MOCK_METHOD3(Observe,
91                void(NotificationType type,
92                     const NotificationSource& source,
93                     const NotificationDetails& details));
94   MOCK_METHOD1(SetDialogDelegate,
95                void(CloudPrintHtmlDialogDelegate* delegate));
96   MOCK_METHOD0(CreateCloudPrintDataSender,
97                scoped_refptr<CloudPrintDataSender>());
98 };
99 
100 class MockCloudPrintHtmlDialogDelegate : public CloudPrintHtmlDialogDelegate {
101  public:
102   MOCK_CONST_METHOD0(IsDialogModal,
103       bool());
104   MOCK_CONST_METHOD0(GetDialogTitle,
105       std::wstring());
106   MOCK_CONST_METHOD0(GetDialogContentURL,
107       GURL());
108   MOCK_CONST_METHOD1(GetWebUIMessageHandlers,
109       void(std::vector<WebUIMessageHandler*>* handlers));
110   MOCK_CONST_METHOD1(GetDialogSize,
111       void(gfx::Size* size));
112   MOCK_CONST_METHOD0(GetDialogArgs,
113       std::string());
114   MOCK_METHOD1(OnDialogClosed,
115       void(const std::string& json_retval));
116   MOCK_METHOD2(OnCloseContents,
117       void(TabContents* source, bool *out_close_dialog));
118 };
119 
120 }  // namespace internal_cloud_print_helpers
121 
122 using internal_cloud_print_helpers::CloudPrintDataSenderHelper;
123 using internal_cloud_print_helpers::CloudPrintDataSender;
124 
125 class MockExternalHtmlDialogUI : public ExternalHtmlDialogUI {
126  public:
127   MOCK_METHOD1(RenderViewCreated,
128       void(RenderViewHost* render_view_host));
129 };
130 
131 class MockCloudPrintDataSenderHelper : public CloudPrintDataSenderHelper {
132  public:
133   // TODO(scottbyer): At some point this probably wants to use a
134   // MockTabContents instead of NULL, and to pre-load it with a bunch
135   // of expects/results.
MockCloudPrintDataSenderHelper()136   MockCloudPrintDataSenderHelper() : CloudPrintDataSenderHelper(NULL) {}
137   MOCK_METHOD1(CallJavascriptFunction, void(const std::wstring&));
138   MOCK_METHOD2(CallJavascriptFunction, void(const std::wstring&,
139                                             const Value& arg1));
140   MOCK_METHOD3(CallJavascriptFunction, void(const std::wstring&,
141                                             const Value& arg1,
142                                             const Value& arg2));
143 };
144 
145 class CloudPrintURLTest : public testing::Test {
146  public:
CloudPrintURLTest()147   CloudPrintURLTest() {}
148 
149  protected:
SetUp()150   virtual void SetUp() {
151     profile_.reset(new TestingProfile());
152   }
153 
154   scoped_ptr<Profile> profile_;
155 };
156 
TEST_F(CloudPrintURLTest,CheckDefaultURLs)157 TEST_F(CloudPrintURLTest, CheckDefaultURLs) {
158   std::string service_url =
159       CloudPrintURL(profile_.get()).
160       GetCloudPrintServiceURL().spec();
161   EXPECT_THAT(service_url, HasSubstr("www.google.com"));
162   EXPECT_THAT(service_url, HasSubstr("cloudprint"));
163 
164   std::string dialog_url =
165       CloudPrintURL(profile_.get()).
166       GetCloudPrintServiceDialogURL().spec();
167   EXPECT_THAT(dialog_url, HasSubstr("www.google.com"));
168   EXPECT_THAT(dialog_url, HasSubstr("/cloudprint/"));
169   EXPECT_THAT(dialog_url, HasSubstr("/client/"));
170   EXPECT_THAT(dialog_url, Not(HasSubstr("cloudprint/cloudprint")));
171   EXPECT_THAT(dialog_url, HasSubstr("/dialog.html"));
172 
173   // Repeat to make sure there isn't a transient glitch.
174   dialog_url =
175       CloudPrintURL(profile_.get()).
176       GetCloudPrintServiceDialogURL().spec();
177   EXPECT_THAT(dialog_url, HasSubstr("www.google.com"));
178   EXPECT_THAT(dialog_url, HasSubstr("/cloudprint/"));
179   EXPECT_THAT(dialog_url, HasSubstr("/client/"));
180   EXPECT_THAT(dialog_url, Not(HasSubstr("cloudprint/cloudprint")));
181   EXPECT_THAT(dialog_url, HasSubstr("/dialog.html"));
182 
183   std::string manage_url =
184       CloudPrintURL(profile_.get()).
185       GetCloudPrintServiceManageURL().spec();
186   EXPECT_THAT(manage_url, HasSubstr("www.google.com"));
187   EXPECT_THAT(manage_url, HasSubstr("/cloudprint/"));
188   EXPECT_THAT(manage_url, Not(HasSubstr("/client/")));
189   EXPECT_THAT(manage_url, Not(HasSubstr("cloudprint/cloudprint")));
190   EXPECT_THAT(manage_url, HasSubstr("/manage"));
191 
192   GURL learn_more_url = CloudPrintURL::GetCloudPrintLearnMoreURL();
193   std::string learn_more_path = learn_more_url.spec();
194   EXPECT_THAT(learn_more_path, HasSubstr("www.google.com"));
195   EXPECT_THAT(learn_more_path, HasSubstr("/support/"));
196   EXPECT_THAT(learn_more_path, HasSubstr("/cloudprint"));
197   EXPECT_TRUE(learn_more_url.has_path());
198   EXPECT_FALSE(learn_more_url.has_query());
199 
200   GURL test_page_url = CloudPrintURL::GetCloudPrintTestPageURL();
201   std::string test_page_path = test_page_url.spec();
202   EXPECT_THAT(test_page_path, HasSubstr("www.google.com"));
203   EXPECT_THAT(test_page_path, HasSubstr("/landing/"));
204   EXPECT_THAT(test_page_path, HasSubstr("/cloudprint/"));
205   EXPECT_TRUE(test_page_url.has_path());
206   EXPECT_TRUE(test_page_url.has_query());
207 }
208 
209 // Testing for CloudPrintDataSender needs a mock WebUI.
210 class CloudPrintDataSenderTest : public testing::Test {
211  public:
CloudPrintDataSenderTest()212   CloudPrintDataSenderTest()
213       : file_thread_(BrowserThread::FILE, &message_loop_),
214         io_thread_(BrowserThread::IO, &message_loop_) {}
215 
216  protected:
SetUp()217   virtual void SetUp() {
218     string16 mock_job_title(ASCIIToUTF16(kMockJobTitle));
219     mock_helper_.reset(new MockCloudPrintDataSenderHelper);
220     print_data_sender_ =
221         new CloudPrintDataSender(mock_helper_.get(),
222                                  mock_job_title,
223                                  std::string("application/pdf"));
224   }
225 
226   scoped_refptr<CloudPrintDataSender> print_data_sender_;
227   scoped_ptr<MockCloudPrintDataSenderHelper> mock_helper_;
228 
229   MessageLoop message_loop_;
230   BrowserThread file_thread_;
231   BrowserThread io_thread_;
232 };
233 
234 // TODO(scottbyer): DISABLED until the binary test file can get
235 // checked in separate from the patch.
TEST_F(CloudPrintDataSenderTest,CanSend)236 TEST_F(CloudPrintDataSenderTest, CanSend) {
237   StringValue mock_job_title(kMockJobTitle);
238   EXPECT_CALL(*mock_helper_,
239               CallJavascriptFunction(_, _, StringValueEq(&mock_job_title))).
240       WillOnce(Return());
241 
242   FilePath test_data_file_name = GetTestDataFileName();
243   BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
244                           NewRunnableMethod(
245                               print_data_sender_.get(),
246                               &CloudPrintDataSender::ReadPrintDataFile,
247                               test_data_file_name));
248   MessageLoop::current()->RunAllPending();
249 }
250 
TEST_F(CloudPrintDataSenderTest,BadFile)251 TEST_F(CloudPrintDataSenderTest, BadFile) {
252   EXPECT_CALL(*mock_helper_, CallJavascriptFunction(_, _, _)).Times(0);
253 
254 #if defined(OS_WIN)
255   FilePath bad_data_file_name(L"/some/file/that/isnot/there");
256 #else
257   FilePath bad_data_file_name("/some/file/that/isnot/there");
258 #endif
259   BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
260                           NewRunnableMethod(
261                               print_data_sender_.get(),
262                               &CloudPrintDataSender::ReadPrintDataFile,
263                              bad_data_file_name));
264   MessageLoop::current()->RunAllPending();
265 }
266 
TEST_F(CloudPrintDataSenderTest,EmptyFile)267 TEST_F(CloudPrintDataSenderTest, EmptyFile) {
268   EXPECT_CALL(*mock_helper_, CallJavascriptFunction(_, _, _)).Times(0);
269 
270   FilePath empty_data_file_name = GetEmptyDataFileName();
271   BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
272                           NewRunnableMethod(
273                               print_data_sender_.get(),
274                               &CloudPrintDataSender::ReadPrintDataFile,
275                               empty_data_file_name));
276   MessageLoop::current()->RunAllPending();
277 }
278 
279 // Testing for CloudPrintFlowHandler needs a mock
280 // CloudPrintHtmlDialogDelegate, mock CloudPrintDataSender, and a mock
281 // WebUI.
282 
283 // Testing for CloudPrintHtmlDialogDelegate needs a mock
284 // CloudPrintFlowHandler.
285 
286 using internal_cloud_print_helpers::MockCloudPrintFlowHandler;
287 using internal_cloud_print_helpers::CloudPrintHtmlDialogDelegate;
288 
289 class CloudPrintHtmlDialogDelegateTest : public testing::Test {
290  public:
CloudPrintHtmlDialogDelegateTest()291   CloudPrintHtmlDialogDelegateTest()
292       : ui_thread_(BrowserThread::UI, &message_loop_) {}
293 
294  protected:
SetUp()295   virtual void SetUp() {
296     FilePath mock_path;
297     string16 mock_title;
298     std::string mock_file_type;
299     MockCloudPrintFlowHandler* handler =
300         new MockCloudPrintFlowHandler(mock_path, mock_title, mock_file_type);
301     mock_flow_handler_ = handler->AsWeakPtr();
302     EXPECT_CALL(*mock_flow_handler_.get(), SetDialogDelegate(_));
303     EXPECT_CALL(*mock_flow_handler_.get(), SetDialogDelegate(NULL));
304     delegate_.reset(new CloudPrintHtmlDialogDelegate(
305         mock_flow_handler_.get(), 100, 100, std::string(), true));
306   }
307 
TearDown()308   virtual void TearDown() {
309     delegate_.reset();
310     if (mock_flow_handler_)
311       delete mock_flow_handler_.get();
312   }
313 
314   MessageLoopForUI message_loop_;
315   BrowserThread ui_thread_;
316   base::WeakPtr<MockCloudPrintFlowHandler> mock_flow_handler_;
317   scoped_ptr<CloudPrintHtmlDialogDelegate> delegate_;
318 };
319 
TEST_F(CloudPrintHtmlDialogDelegateTest,BasicChecks)320 TEST_F(CloudPrintHtmlDialogDelegateTest, BasicChecks) {
321   EXPECT_TRUE(delegate_->IsDialogModal());
322   EXPECT_THAT(delegate_->GetDialogContentURL().spec(),
323               StrEq(chrome::kCloudPrintResourcesURL));
324   EXPECT_TRUE(delegate_->GetDialogTitle().empty());
325 
326   bool close_dialog = false;
327   delegate_->OnCloseContents(NULL, &close_dialog);
328   EXPECT_TRUE(close_dialog);
329 }
330 
TEST_F(CloudPrintHtmlDialogDelegateTest,OwnedFlowDestroyed)331 TEST_F(CloudPrintHtmlDialogDelegateTest, OwnedFlowDestroyed) {
332   delegate_.reset();
333   EXPECT_THAT(mock_flow_handler_.get(), IsNull());
334 }
335 
TEST_F(CloudPrintHtmlDialogDelegateTest,UnownedFlowLetGo)336 TEST_F(CloudPrintHtmlDialogDelegateTest, UnownedFlowLetGo) {
337   std::vector<WebUIMessageHandler*> handlers;
338   delegate_->GetWebUIMessageHandlers(&handlers);
339   delegate_.reset();
340   EXPECT_THAT(mock_flow_handler_.get(), NotNull());
341 }
342 
343 // Testing for ExternalHtmlDialogUI needs a mock TabContents, mock
344 // CloudPrintHtmlDialogDelegate (provided through the mock
345 // tab_contents)
346 
347 // Testing for PrintDialogCloud needs a mock Browser.
348