| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <atlbase.h> | 5 #include <atlbase.h> |
| 6 #include <atlcom.h> | 6 #include <atlcom.h> |
| 7 | 7 |
| 8 #include "base/scoped_comptr_win.h" | 8 #include "base/scoped_comptr_win.h" |
| 9 #include "base/thread.h" | 9 #include "base/thread.h" |
| 10 #include "chrome_frame/bho.h" | 10 #include "chrome_frame/bho.h" |
| 11 #include "chrome_frame/urlmon_moniker.h" | 11 //#include "chrome_frame/urlmon_moniker.h" |
| 12 #include "chrome_frame/test/test_server.h" | 12 #include "chrome_frame/test/test_server.h" |
| 13 #include "chrome_frame/test/chrome_frame_test_utils.h" | 13 #include "chrome_frame/test/chrome_frame_test_utils.h" |
| 14 #include "chrome_frame/test/urlmon_moniker_tests.h" | 14 #include "chrome_frame/test/urlmon_moniker_tests.h" |
| 15 #include "gmock/gmock.h" | 15 #include "gmock/gmock.h" |
| 16 #include "gtest/gtest.h" | 16 #include "gtest/gtest.h" |
| 17 | 17 |
| 18 #define GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING | 18 #define GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING |
| 19 #include "testing/gmock_mutant.h" | 19 #include "testing/gmock_mutant.h" |
| 20 | 20 |
| 21 using testing::_; | 21 using testing::_; |
| 22 using testing::CreateFunctor; | 22 using testing::CreateFunctor; |
| 23 using testing::Eq; | 23 using testing::Eq; |
| 24 using testing::Invoke; | 24 using testing::Invoke; |
| 25 using testing::SetArgumentPointee; | 25 using testing::SetArgumentPointee; |
| 26 using testing::StrEq; | 26 using testing::StrEq; |
| 27 using testing::Return; | 27 using testing::Return; |
| 28 using testing::WithArg; | 28 using testing::DoAll; |
| 29 using testing::WithArgs; | 29 using testing::WithArgs; |
| 30 | 30 |
| 31 |
| 31 static int kUrlmonMonikerTimeoutSec = 5; | 32 static int kUrlmonMonikerTimeoutSec = 5; |
| 32 | 33 |
| 33 namespace { | 34 namespace { |
| 34 const char kTestContent[] = "<html><head>" | 35 const char kTestContent[] = "<html><head>" |
| 35 "<meta http-equiv=\"X-UA-Compatible\" content=\"chrome=1\" />" | 36 "<meta http-equiv=\"X-UA-Compatible\" content=\"chrome=1\" />" |
| 36 "</head><body>Test HTML content</body></html>"; | 37 "</head><body>Test HTML content</body></html>"; |
| 37 } // end namespace | 38 } // end namespace |
| 38 | 39 |
| 39 class UrlmonMonikerTest : public testing::Test { | 40 class UrlmonMonikerTest : public testing::Test { |
| 40 protected: | 41 protected: |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 protected: | 82 protected: |
| 82 scoped_ptr<test_server::SimpleWebServer> server_; | 83 scoped_ptr<test_server::SimpleWebServer> server_; |
| 83 test_server::SimpleResponse default_response_; | 84 test_server::SimpleResponse default_response_; |
| 84 ScopedHandle ready_; | 85 ScopedHandle ready_; |
| 85 }; | 86 }; |
| 86 | 87 |
| 87 // Helper class for running tests that rely on the NavigationManager. | 88 // Helper class for running tests that rely on the NavigationManager. |
| 88 class UrlmonMonikerTestManager { | 89 class UrlmonMonikerTestManager { |
| 89 public: | 90 public: |
| 90 explicit UrlmonMonikerTestManager(const wchar_t* test_url) { | 91 explicit UrlmonMonikerTestManager(const wchar_t* test_url) { |
| 91 mock_mgr_.RegisterThreadInstance(); | |
| 92 mock_mgr_.set_url(test_url); | |
| 93 EXPECT_EQ(true, MonikerPatch::Initialize()); | 92 EXPECT_EQ(true, MonikerPatch::Initialize()); |
| 94 } | 93 } |
| 95 | 94 |
| 96 ~UrlmonMonikerTestManager() { | 95 ~UrlmonMonikerTestManager() { |
| 97 MonikerPatch::Uninitialize(); | 96 MonikerPatch::Uninitialize(); |
| 98 mock_mgr_.UnregisterThreadInstance(); | |
| 99 } | 97 } |
| 100 | 98 |
| 101 chrome_frame_test::TimedMsgLoop& loop() { | 99 chrome_frame_test::TimedMsgLoop& loop() { |
| 102 return loop_; | 100 return loop_; |
| 103 } | 101 } |
| 104 | 102 |
| 105 TestNavigationManager& nav_manager() { | |
| 106 return mock_mgr_; | |
| 107 } | |
| 108 | |
| 109 protected: | 103 protected: |
| 110 TestNavigationManager mock_mgr_; | |
| 111 chrome_frame_test::TimedMsgLoop loop_; | 104 chrome_frame_test::TimedMsgLoop loop_; |
| 112 }; | 105 }; |
| 113 | 106 |
| 107 ACTION_P(SetBindInfo, is_async) { |
| 108 DWORD* flags = arg0; |
| 109 BINDINFO* bind_info = arg1; |
| 110 |
| 111 DCHECK(flags); |
| 112 DCHECK(bind_info); |
| 113 DCHECK(bind_info->cbSize >= sizeof(BINDINFO)); |
| 114 |
| 115 *flags = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA; |
| 116 if (is_async) |
| 117 *flags |= BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE; |
| 118 |
| 119 bind_info->dwBindVerb = BINDVERB_GET; |
| 120 memset(&bind_info->stgmedData, 0, sizeof(STGMEDIUM)); |
| 121 bind_info->grfBindInfoF = 0; |
| 122 bind_info->szCustomVerb = NULL; |
| 123 } |
| 124 |
| 114 // Wraps the MockBindStatusCallbackImpl mock object and allows the user | 125 // Wraps the MockBindStatusCallbackImpl mock object and allows the user |
| 115 // to specify expectations on the callback object. | 126 // to specify expectations on the callback object. |
| 116 class UrlmonMonikerTestCallback { | 127 class UrlmonMonikerTestCallback { |
| 117 public: | 128 public: |
| 118 explicit UrlmonMonikerTestCallback(UrlmonMonikerTestManager* mgr) | 129 explicit UrlmonMonikerTestCallback(UrlmonMonikerTestManager* mgr) |
| 119 : mgr_(mgr) { | 130 : mgr_(mgr), clip_format_(0) { |
| 120 } | 131 } |
| 121 | 132 |
| 122 ~UrlmonMonikerTestCallback() { | 133 ~UrlmonMonikerTestCallback() { |
| 123 } | 134 } |
| 124 | 135 |
| 125 typedef enum GetBindInfoExpectations { | 136 typedef enum GetBindInfoExpectations { |
| 126 EXPECT_NO_CALL, | 137 EXPECT_NO_CALL, |
| 127 REQUEST_SYNCHRONOUS, | 138 REQUEST_SYNCHRONOUS, |
| 128 REQUEST_ASYNCHRONOUS, | 139 REQUEST_ASYNCHRONOUS, |
| 129 } GET_BIND_INFO_EXPECTATION; | 140 } GET_BIND_INFO_EXPECTATION; |
| 130 | 141 |
| 131 // Sets gmock expectations for the IBindStatusCallback mock object. | 142 // Sets gmock expectations for the IBindStatusCallback mock object. |
| 132 void SetCallbackExpectations(GetBindInfoExpectations bind_info_handling, | 143 void SetCallbackExpectations(GetBindInfoExpectations bind_info_handling, |
| 133 HRESULT data_available_response, | 144 HRESULT data_available_response, |
| 134 bool quit_loop_on_stop) { | 145 bool quit_loop_on_stop) { |
| 135 EXPECT_CALL(callback_, OnProgress(_, _, _, _)) | 146 EXPECT_CALL(callback_, OnProgress(_, _, _, _)) |
| 136 .WillRepeatedly(Return(S_OK)); | 147 .WillRepeatedly(Return(S_OK)); |
| 137 | 148 |
| 138 if (bind_info_handling == REQUEST_ASYNCHRONOUS) { | 149 if (bind_info_handling == REQUEST_ASYNCHRONOUS) { |
| 139 EXPECT_CALL(callback_, GetBindInfo(_, _)) | 150 EXPECT_CALL(callback_, GetBindInfo(_, _)) |
| 140 .WillOnce(DoAll( | 151 .WillOnce(DoAll(SetBindInfo(true), Return(S_OK))); |
| 141 WithArgs<0, 1>( | |
| 142 Invoke(&MockBindStatusCallbackImpl::SetAsyncBindInfo)), | |
| 143 Return(S_OK))); | |
| 144 } else if (bind_info_handling == REQUEST_SYNCHRONOUS) { | 152 } else if (bind_info_handling == REQUEST_SYNCHRONOUS) { |
| 145 EXPECT_CALL(callback_, GetBindInfo(_, _)) | 153 EXPECT_CALL(callback_, GetBindInfo(_, _)) |
| 146 .WillOnce(DoAll( | 154 .WillOnce(DoAll(SetBindInfo(false), Return(S_OK))); |
| 147 WithArgs<0, 1>( | |
| 148 Invoke(&MockBindStatusCallbackImpl::SetSyncBindInfo)), | |
| 149 Return(S_OK))); | |
| 150 } else { | 155 } else { |
| 151 DCHECK(bind_info_handling == EXPECT_NO_CALL); | 156 DCHECK(bind_info_handling == EXPECT_NO_CALL); |
| 152 } | 157 } |
| 153 | 158 |
| 154 EXPECT_CALL(callback_, OnStartBinding(_, _)) | 159 EXPECT_CALL(callback_, OnStartBinding(_, _)) |
| 155 .WillOnce(Return(S_OK)); | 160 .WillOnce(Return(S_OK)); |
| 156 | 161 |
| 157 EXPECT_CALL(callback_, OnDataAvailable(_, _, _, _)) | 162 EXPECT_CALL(callback_, OnDataAvailable(_, _, _, _)) |
| 158 .WillRepeatedly(Return(data_available_response)); | 163 .WillRepeatedly(Return(data_available_response)); |
| 159 | 164 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 185 return hr; | 190 return hr; |
| 186 } | 191 } |
| 187 | 192 |
| 188 IBindStatusCallback* callback() { | 193 IBindStatusCallback* callback() { |
| 189 return &callback_; | 194 return &callback_; |
| 190 } | 195 } |
| 191 | 196 |
| 192 protected: | 197 protected: |
| 193 CComObjectStackEx<MockBindStatusCallbackImpl> callback_; | 198 CComObjectStackEx<MockBindStatusCallbackImpl> callback_; |
| 194 UrlmonMonikerTestManager* mgr_; | 199 UrlmonMonikerTestManager* mgr_; |
| 200 CLIPFORMAT clip_format_; |
| 195 }; | 201 }; |
| 196 | 202 |
| 197 // Tests synchronously binding to a moniker and downloading the target. | 203 // Tests synchronously binding to a moniker and downloading the target. |
| 198 TEST_F(UrlmonMonikerTest, BindToStorageSynchronous) { | 204 TEST_F(UrlmonMonikerTest, BindToStorageSynchronous) { |
| 199 const wchar_t test_url[] = L"http://localhost:43210/"; | 205 const wchar_t test_url[] = L"http://localhost:43210/"; |
| 200 UrlmonMonikerTestManager test(test_url); | 206 UrlmonMonikerTestManager test(test_url); |
| 201 UrlmonMonikerTestCallback callback(&test); | 207 UrlmonMonikerTestCallback callback(&test); |
| 202 | 208 |
| 203 RunTestServer server_thread; | 209 RunTestServer server_thread; |
| 204 EXPECT_TRUE(server_thread.Start()); | 210 EXPECT_TRUE(server_thread.Start()); |
| 205 | 211 |
| 206 callback.SetCallbackExpectations( | 212 callback.SetCallbackExpectations( |
| 207 UrlmonMonikerTestCallback::REQUEST_SYNCHRONOUS, S_OK, false); | 213 UrlmonMonikerTestCallback::REQUEST_SYNCHRONOUS, S_OK, false); |
| 208 | 214 |
| 209 ScopedComPtr<IBindCtx> bind_ctx; | 215 ScopedComPtr<IBindCtx> bind_ctx; |
| 210 HRESULT hr = callback.CreateUrlMonikerAndBindToStorage(test_url, | 216 HRESULT hr = callback.CreateUrlMonikerAndBindToStorage(test_url, |
| 211 bind_ctx.Receive()); | 217 bind_ctx.Receive()); |
| 212 // The download should have happened synchronously, so we don't expect | 218 // The download should have happened synchronously, so we don't expect |
| 213 // MK_S_ASYNCHRONOUS or any errors. | 219 // MK_S_ASYNCHRONOUS or any errors. |
| 214 EXPECT_EQ(S_OK, hr); | 220 EXPECT_EQ(S_OK, hr); |
| 215 | 221 |
| 216 IBindCtx* release = bind_ctx.Detach(); | 222 IBindCtx* release = bind_ctx.Detach(); |
| 217 EXPECT_EQ(0, release->Release()); | 223 EXPECT_EQ(0, release->Release()); |
| 218 | 224 |
| 219 server_thread.Stop(); | 225 server_thread.Stop(); |
| 220 | |
| 221 EXPECT_FALSE(test.nav_manager().HasRequestData()); | |
| 222 } | 226 } |
| 223 | 227 |
| 224 // Tests asynchronously binding to a moniker and downloading the target. | 228 // Tests asynchronously binding to a moniker and downloading the target. |
| 225 TEST_F(UrlmonMonikerTest, BindToStorageAsynchronous) { | 229 TEST_F(UrlmonMonikerTest, BindToStorageAsynchronous) { |
| 226 const wchar_t test_url[] = L"http://localhost:43210/"; | 230 const wchar_t test_url[] = L"http://localhost:43210/"; |
| 227 UrlmonMonikerTestManager test(test_url); | 231 UrlmonMonikerTestManager test(test_url); |
| 228 UrlmonMonikerTestCallback callback(&test); | 232 UrlmonMonikerTestCallback callback(&test); |
| 229 | 233 |
| 230 test_server::SimpleWebServer server(43210); | 234 test_server::SimpleWebServer server(43210); |
| 231 test_server::SimpleResponse default_response("/", kTestContent); | 235 test_server::SimpleResponse default_response("/", kTestContent); |
| 232 server.AddResponse(&default_response); | 236 server.AddResponse(&default_response); |
| 233 | 237 |
| 234 callback.SetCallbackExpectations( | 238 callback.SetCallbackExpectations( |
| 235 UrlmonMonikerTestCallback::REQUEST_ASYNCHRONOUS, S_OK, true); | 239 UrlmonMonikerTestCallback::REQUEST_ASYNCHRONOUS, S_OK, true); |
| 236 | 240 |
| 237 ScopedComPtr<IBindCtx> bind_ctx; | 241 ScopedComPtr<IBindCtx> bind_ctx; |
| 238 HRESULT hr = callback.CreateUrlMonikerAndBindToStorage(test_url, | 242 HRESULT hr = callback.CreateUrlMonikerAndBindToStorage(test_url, |
| 239 bind_ctx.Receive()); | 243 bind_ctx.Receive()); |
| 240 EXPECT_EQ(MK_S_ASYNCHRONOUS, hr); | 244 EXPECT_EQ(MK_S_ASYNCHRONOUS, hr); |
| 241 test.loop().RunFor(kUrlmonMonikerTimeoutSec); | 245 test.loop().RunFor(kUrlmonMonikerTimeoutSec); |
| 242 | 246 |
| 243 IBindCtx* release = bind_ctx.Detach(); | 247 IBindCtx* release = bind_ctx.Detach(); |
| 244 EXPECT_EQ(0, release->Release()); | 248 EXPECT_EQ(0, release->Release()); |
| 245 | |
| 246 EXPECT_FALSE(test.nav_manager().HasRequestData()); | |
| 247 } | 249 } |
| 248 | 250 |
| 249 // Responds with the Chrome mime type. | 251 // Responds with the Chrome mime type. |
| 250 class ResponseWithContentType : public test_server::SimpleResponse { | 252 class ResponseWithContentType : public test_server::SimpleResponse { |
| 251 public: | 253 public: |
| 252 ResponseWithContentType(const char* request_path, | 254 ResponseWithContentType(const char* request_path, |
| 253 const std::string& contents) | 255 const std::string& contents) |
| 254 : test_server::SimpleResponse(request_path, contents) { | 256 : test_server::SimpleResponse(request_path, contents) { |
| 255 } | 257 } |
| 256 virtual bool GetContentType(std::string* content_type) const { | 258 virtual bool GetContentType(std::string* content_type) const { |
| 257 *content_type = WideToASCII(kChromeMimeType); | 259 *content_type = WideToASCII(kChromeMimeType); |
| 258 return true; | 260 return true; |
| 259 } | 261 } |
| 260 }; | 262 }; |
| 261 | 263 |
| 264 /* |
| 262 // Downloads a document asynchronously and then verifies that the downloaded | 265 // Downloads a document asynchronously and then verifies that the downloaded |
| 263 // contents were cached and the cache contents are correct. | 266 // contents were cached and the cache contents are correct. |
| 264 // TODO(tommi): Fix and re-enable. | 267 // TODO(tommi): Fix and re-enable. |
| 265 // http://code.google.com/p/chromium/issues/detail?id=39415 | 268 // http://code.google.com/p/chromium/issues/detail?id=39415 |
| 266 TEST_F(UrlmonMonikerTest, BindToStorageSwitchContent) { | 269 TEST_F(UrlmonMonikerTest, BindToStorageSwitchContent) { |
| 267 const wchar_t test_url[] = L"http://localhost:43210/"; | 270 const wchar_t test_url[] = L"http://localhost:43210/"; |
| 268 UrlmonMonikerTestManager test(test_url); | 271 UrlmonMonikerTestManager test(test_url); |
| 269 UrlmonMonikerTestCallback callback(&test); | 272 UrlmonMonikerTestCallback callback(&test); |
| 270 | 273 |
| 271 test_server::SimpleWebServer server(43210); | 274 test_server::SimpleWebServer server(43210); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 UrlmonMonikerTestCallback callback2(&test); | 336 UrlmonMonikerTestCallback callback2(&test); |
| 334 callback2.SetCallbackExpectations( | 337 callback2.SetCallbackExpectations( |
| 335 UrlmonMonikerTestCallback::EXPECT_NO_CALL, S_OK, false); | 338 UrlmonMonikerTestCallback::EXPECT_NO_CALL, S_OK, false); |
| 336 hr = callback2.CreateUrlMonikerAndBindToStorage(test_url, NULL); | 339 hr = callback2.CreateUrlMonikerAndBindToStorage(test_url, NULL); |
| 337 // S_OK means that the operation completed synchronously. | 340 // S_OK means that the operation completed synchronously. |
| 338 // Otherwise we'd get MK_S_ASYNCHRONOUS. | 341 // Otherwise we'd get MK_S_ASYNCHRONOUS. |
| 339 EXPECT_EQ(S_OK, hr); | 342 EXPECT_EQ(S_OK, hr); |
| 340 } | 343 } |
| 341 } | 344 } |
| 342 | 345 |
| 346 */ |
| OLD | NEW |