Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: chrome_frame/test/urlmon_moniker_unittest.cc

Issue 1589013: Switch renderer in Moniker patch... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/file_util.h"
9 #include "base/path_service.h"
8 #include "base/scoped_comptr_win.h" 10 #include "base/scoped_comptr_win.h"
9 #include "chrome_frame/bho.h" 11 #include "chrome_frame/urlmon_bind_status_callback.h"
10 #include "chrome_frame/urlmon_moniker.h"
11 #include "chrome_frame/test/urlmon_moniker_tests.h" 12 #include "chrome_frame/test/urlmon_moniker_tests.h"
12 #include "gmock/gmock.h" 13
13 #include "gtest/gtest.h"
14
15 using testing::_;
16 using testing::Return; 14 using testing::Return;
17 using testing::WithArg;
18 using testing::WithArgs;
19 using testing::SetArgumentPointee;
20 using testing::StrEq;
21 using testing::Eq; 15 using testing::Eq;
22 16
23 class UrlmonMonikerTest : public testing::Test { 17 class MonikerPatchTest : public testing::Test {
24 protected: 18 protected:
25 UrlmonMonikerTest() { 19 MonikerPatchTest() {
26 } 20 }
21
22 virtual void SetUp() {
23 PathService::Get(base::DIR_SOURCE_ROOT, &test_file_path_);
24 test_file_path_ = test_file_path_.Append(FILE_PATH_LITERAL("chrome_frame"))
25 .Append(FILE_PATH_LITERAL("test"))
26 .Append(FILE_PATH_LITERAL("data"));
27 }
28
29 bool ReadFileAsString(const wchar_t* file_name, std::string* file_contents) {
30 EXPECT_TRUE(file_name);
31 FilePath file_path = test_file_path_.Append(file_name);
32 return file_util::ReadFileToString(file_path, file_contents);
33 }
34
35 static bool StringToStream(const std::string& data, IStream** ret) {
36 EXPECT_TRUE(!data.empty());
37
38 ScopedComPtr<IStream> stream;
39 HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, stream.Receive());
40 EXPECT_HRESULT_SUCCEEDED(hr);
41 if (FAILED(hr)) {
42 return false;
43 }
44
45 DWORD written = 0;
46 hr = stream->Write(data.c_str(), data.size(), &written);
47 EXPECT_HRESULT_SUCCEEDED(hr);
48 EXPECT_EQ(data.size(), written);
49
50 bool result = false;
51 if (SUCCEEDED(hr)) {
52 RewindStream(stream);
53 *ret = stream.Detach();
54 result = true;
55 }
56
57 return result;
58 }
59
60 FilePath test_file_path_;
27 }; 61 };
28 62
29 // Tests the ReadStreamCache class by writing content into a stream object 63 // Tests the CacheStream class by writing content into a stream object
30 // and verify that reading that stream through the ReadStreamCache class 64 // and verify that reading that stream back
31 // reads the correct content and also verifies that ReadStreamCache caches 65 TEST_F(MonikerPatchTest, CacheStream) {
32 // all the reads. 66 const char data[] = "ReadStreamCacheTest";
33 TEST_F(UrlmonMonikerTest, ReadStreamCache) { 67 char ret[2 * sizeof(data)] = {0};
34 CComObjectStackEx<ReadStreamCache> read_stream;
35 EXPECT_EQ(NULL, read_stream.cache());
36
37 ScopedComPtr<IStream> test_stream;
38 ::CreateStreamOnHGlobal(NULL, TRUE, test_stream.Receive());
39 EXPECT_TRUE(NULL != test_stream);
40 const char test_string[] = "ReadStreamCacheTest";
41 DWORD written;
42 EXPECT_HRESULT_SUCCEEDED(test_stream->Write(test_string, sizeof(test_string),
43 &written));
44 EXPECT_HRESULT_SUCCEEDED(RewindStream(test_stream));
45
46 read_stream.SetDelegate(test_stream);
47
48 char buffer[0xff];
49 DWORD read = 0; 68 DWORD read = 0;
50 EXPECT_HRESULT_SUCCEEDED(read_stream.Read(buffer, sizeof(buffer), &read)); 69
51 EXPECT_EQ(read, sizeof(test_string)); 70 // Test 1: empty stream reads nothing
52 EXPECT_EQ(read_stream.GetCacheSize(), sizeof(test_string)); 71 CComObjectStackEx<CacheStream> cache_stream1;
53 read_stream.RewindCache(); 72 EXPECT_EQ(E_PENDING, cache_stream1.Read(ret, sizeof(ret), &read));
54 IStream* cache = read_stream.cache(); 73 EXPECT_EQ(0, read);
55 EXPECT_TRUE(NULL != cache); 74
56 if (cache) { 75 // Test 2: Read from initialized cache
57 read = 0; 76 CComObjectStackEx<CacheStream> cache_stream2;
58 EXPECT_HRESULT_SUCCEEDED(cache->Read(buffer, sizeof(buffer), &read)); 77 cache_stream2.Initialize(data, sizeof(data));
59 EXPECT_EQ(read, sizeof(test_string)); 78 EXPECT_HRESULT_SUCCEEDED(cache_stream2.Read(ret, sizeof(ret), &read));
60 EXPECT_EQ(0, memcmp(test_string, buffer, sizeof(test_string))); 79 EXPECT_EQ(sizeof(data), read);
61 } 80 EXPECT_EQ(std::string(data), std::string(ret));
62 } 81
63 82 read = 0;
64 // Verifies that we can override bind results by using the SimpleBindingImpl 83 EXPECT_EQ(E_PENDING, cache_stream2.Read(ret, sizeof(ret), &read));
65 // class. 84 EXPECT_EQ(0, read);
66 TEST_F(UrlmonMonikerTest, SimpleBindingImpl1) { 85 }
67 CComObjectStackEx<SimpleBindingImpl> test; 86
68 ScopedComPtr<IBinding> binding; 87 ACTION_P3(ReadStream, buffer, size, ret) {
69 binding.QueryFrom(&test); 88 EXPECT_EQ(TYMED_ISTREAM, arg3->tymed);
70 EXPECT_TRUE(binding != NULL); 89 *ret = arg3->pstm->Read(buffer, *size, size);
71 test.OverrideBindResults(E_INVALIDARG); 90 }
72 DWORD hr = E_UNEXPECTED; 91
73 EXPECT_HRESULT_SUCCEEDED(binding->GetBindResult(NULL, &hr, NULL, NULL)); 92 // Tests the implementation of BSCBFeedData to feed data to the
74 EXPECT_EQ(E_INVALIDARG, hr); 93 // specified IBindStatusCallback
75 test.OverrideBindResults(E_ACCESSDENIED); 94 TEST_F(MonikerPatchTest, BSCBFeedData) {
76 // {1AF15145-104B-4bd8-AA4F-97CEFD40D370} - just something non-null.
77 GUID guid = { 0x1af15145, 0x104b, 0x4bd8,
78 { 0xaa, 0x4f, 0x97, 0xce, 0xfd, 0x40, 0xd3, 0x70 } };
79 EXPECT_HRESULT_SUCCEEDED(binding->GetBindResult(&guid, &hr, NULL, NULL));
80 EXPECT_EQ(E_ACCESSDENIED, hr);
81 EXPECT_TRUE(guid == GUID_NULL);
82 }
83
84 // Tests the SimpleBindingImpl class with a delegate. Verifies that the
85 // delegate gets called and also that we can override the bind results.
86 TEST_F(UrlmonMonikerTest, SimpleBindingImpl2) {
87 CComObjectStackEx<MockBindingImpl> mock;
88 CComObjectStackEx<SimpleBindingImpl> test;
89
90 EXPECT_CALL(mock, QueryService(_, _, _))
91 .WillOnce(Return(E_ACCESSDENIED));
92 EXPECT_CALL(mock, GetBindResult(_, _, _, _))
93 .WillRepeatedly(DoAll(SetArgumentPointee<1>(E_ACCESSDENIED),
94 Return(S_OK)));
95 EXPECT_CALL(mock, Abort())
96 .WillOnce(Return(E_ACCESSDENIED));
97
98 ScopedComPtr<IServiceProvider> svc;
99 svc.QueryFrom(test.GetUnknown());
100 EXPECT_TRUE(svc == NULL);
101
102 test.SetDelegate(&mock);
103
104 // Now we should have access to IServiceProvider
105 svc.QueryFrom(test.GetUnknown());
106 EXPECT_TRUE(svc != NULL);
107
108 ScopedComPtr<IUnknown> unk;
109 EXPECT_EQ(E_ACCESSDENIED, svc->QueryService(GUID_NULL, IID_NULL,
110 reinterpret_cast<void**>(unk.Receive())));
111
112 // Call through to the mock's GetBindResult implementation.
113 DWORD result;
114 test.GetBindResult(NULL, &result, NULL, NULL);
115 EXPECT_TRUE(result == E_ACCESSDENIED);
116 // Let the binding override the result code.
117 test.OverrideBindResults(INET_E_TERMINATED_BIND);
118 test.GetBindResult(NULL, &result, NULL, NULL);
119 EXPECT_TRUE(result == INET_E_TERMINATED_BIND);
120
121 EXPECT_EQ(E_ACCESSDENIED, test.Abort());
122 }
123
124 // Tests the RequestData class. Content is fed to the object via OnX methods
125 // and then we verify that the cached content is correct by calling
126 // FireHttpNegotiateEvents and see if the notifications contain the correct
127 // content.
128 TEST_F(UrlmonMonikerTest, RequestHeaders) {
129 scoped_refptr<RequestData> test(new RequestData());
130 test->Initialize(NULL);
131
132 const wchar_t url[] = L"http://www.chromium.org";
133 const wchar_t begin_headers[] = L"Cookie: endilega\r\n";
134 const wchar_t request_headers[] = L"GET / HTTP/1.0\r\nHost: cough\r\n\rn";
135 const wchar_t response_headers[] = L"HTTP 200 OK\r\nHave-a: good-day\r\n\r\n";
136 const wchar_t additional_headers[] = L"Referer: http://foo.com\r\n";
137
138 // Null pointers should be ignored.
139 RequestHeaders* headers = test->headers();
140 EXPECT_TRUE(NULL != headers);
141 headers->OnBeginningTransaction(NULL, NULL, NULL);
142 headers->OnBeginningTransaction(url, begin_headers, additional_headers);
143 headers->OnResponse(500, NULL, NULL);
144 headers->OnResponse(200, response_headers, request_headers);
145
146 CComObjectStackEx<MockHttpNegotiateImpl> mock;
147 EXPECT_CALL(mock, BeginningTransaction(StrEq(url), StrEq(begin_headers),
148 _, _))
149 .WillOnce(Return(S_OK));
150 EXPECT_CALL(mock, OnResponse(Eq(200), StrEq(response_headers),
151 StrEq(request_headers), _))
152 .WillOnce(Return(S_OK));
153
154 EXPECT_EQ(0, headers->request_url().compare(url));
155
156 headers->FireHttpNegotiateEvents(&mock);
157 }
158
159 // Tests the HTML content portion of the RequestData class.
160 // Here we provide content in the form of a stream object and call
161 // OnDataAvailable to make the object cache the contents.
162 // Then we fetch the cached content stream by calling
163 // GetResetCachedContentStream and verify that it's contents are correct.
164 // In order to also test when data is cached outside of OnDataAvailable
165 // calls, we also call DelegateDataRead. In this test we simply use the
166 // original content again which will make the end results that the cached
167 // content should be double the test content.
168 TEST_F(UrlmonMonikerTest, RequestDataContent) {
169 scoped_refptr<RequestData> test(new RequestData());
170 test->Initialize(NULL);
171
172 CComObjectStackEx<MockBindStatusCallbackImpl> mock; 95 CComObjectStackEx<MockBindStatusCallbackImpl> mock;
173 96 const char data[] = "ReadStreamCacheTest";
174 ScopedComPtr<IStream> data; 97 const DWORD size = sizeof(data);
175 ::CreateStreamOnHGlobal(NULL, TRUE, data.Receive()); 98 const CLIPFORMAT cf = 0xd0d0;
176 const char content[] = "<html><head>" 99 const DWORD flags = BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION;
177 "<meta http-equiv=\"X-UA-Compatible\" content=\"chrome=1\" />" 100 const DWORD kArbitraryreadSize = 0xdeadbabe;
178 "</head><body>Test HTML content</body></html>"; 101
179 data->Write(content, sizeof(content) - 1, NULL); 102 char read_buffer1[size] = {0}, read_buffer2[size] = {0};
180 STATSTG stat = {0}; 103 DWORD read_size1 = size, read_size2 = kArbitraryreadSize;
181 data->Stat(&stat, STATFLAG_NONAME); 104 HRESULT ret1 = E_FAIL, ret2 = E_FAIL;
182 DCHECK(stat.cbSize.LowPart == (sizeof(content) - 1)); 105
183 RewindStream(data); 106 EXPECT_CALL(mock, OnDataAvailable(flags, size,
184 107 testing::Field(&FORMATETC::cfFormat, cf),
185 FORMATETC format = {0}; 108 testing::Field(&STGMEDIUM::tymed, TYMED_ISTREAM)))
186 format.cfFormat = ::RegisterClipboardFormat(L"application/chromepage"); 109 .WillOnce(testing::DoAll(
187 format.tymed = TYMED_ISTREAM; 110 ReadStream(read_buffer1, &read_size1, &ret1),
188 STGMEDIUM storage = {0}; 111 ReadStream(read_buffer2, &read_size2, &ret2),
189 storage.tymed = TYMED_ISTREAM;
190 storage.pstm = data;
191
192 DWORD flags = BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION |
193 BSCF_DATAFULLYAVAILABLE;
194
195 EXPECT_CALL(mock, OnDataAvailable(Eq(flags), Eq(stat.cbSize.LowPart), _, _))
196 .WillOnce(DoAll(
197 WithArgs<3>(testing::Invoke(
198 &MockBindStatusCallbackImpl::ReadAllData)),
199 Return(S_OK))); 112 Return(S_OK)));
200 113
201 size_t bytes_read = 0; 114 EXPECT_HRESULT_SUCCEEDED(CacheStream::BSCBFeedData(&mock, data, size, cf,
202 test->DelegateDataRead(&mock, flags, stat.cbSize.LowPart, &format, &storage, 115 flags));
203 &bytes_read); 116
204 117 EXPECT_HRESULT_SUCCEEDED(ret1);
205 DCHECK(bytes_read == stat.cbSize.LowPart); 118 EXPECT_STREQ(data, read_buffer1);
206 DCHECK(test->GetCachedContentSize() == bytes_read); 119 EXPECT_EQ(size, read_size1);
207 120
208 // Also test that the CacheAll method appends the stream. 121 EXPECT_EQ(E_PENDING, ret2);
209 RewindStream(data); 122 EXPECT_STREQ("", read_buffer2);
210 test->CacheAll(data); 123 EXPECT_EQ(kArbitraryreadSize, read_size2);
211 DCHECK(test->GetCachedContentSize() == (bytes_read * 2)); 124 }
212 125
213 ScopedComPtr<IStream> cache; 126 const wchar_t kSmallHtmlMetaTag[] = L"sub_frame1.html";
214 EXPECT_HRESULT_SUCCEEDED(test->GetResetCachedContentStream(cache.Receive())); 127 const wchar_t kSmallHtmlNoMetaTag[] = L"host_browser.html";
215 if (cache) { 128
216 char buffer[0xffff]; 129 // Test various aspects of the SniffData class
217 DCHECK((bytes_read * 2) <= sizeof(buffer)); 130 TEST_F(MonikerPatchTest, SniffDataMetaTag) {
218 DWORD read = 0; 131 std::string small_html_meta_tag, small_html_no_meta_tag;
219 cache->Read(buffer, sizeof(buffer), &read); 132 ASSERT_TRUE(ReadFileAsString(kSmallHtmlMetaTag, &small_html_meta_tag));
220 EXPECT_EQ(read, bytes_read * 2); 133 ASSERT_TRUE(ReadFileAsString(kSmallHtmlNoMetaTag, &small_html_no_meta_tag));
221 EXPECT_EQ(0, memcmp(content, buffer, sizeof(content) - 1)); 134
222 EXPECT_EQ(0, memcmp(content, buffer + sizeof(content) - 1, 135 ScopedComPtr<IStream> stream_with_meta, stream_no_meta;
223 sizeof(content) - 1)); 136 ASSERT_TRUE(StringToStream(small_html_meta_tag, stream_with_meta.Receive()));
224 } 137 ASSERT_TRUE(StringToStream(small_html_no_meta_tag,
225 } 138 stream_no_meta.Receive()));
226 139
140 // Initialize 2 sniffers 1 with meta tag and 1 without.
141 SniffData sniffer1, sniffer2;
142 EXPECT_TRUE(sniffer1.InitializeCache(std::wstring()));
143 EXPECT_TRUE(sniffer2.InitializeCache(std::wstring()));
144 EXPECT_HRESULT_SUCCEEDED(sniffer1.ReadIntoCache(stream_with_meta, true));
145 EXPECT_HRESULT_SUCCEEDED(sniffer2.ReadIntoCache(stream_no_meta, true));
146
147 // Verify renderer type and size read.
148 EXPECT_TRUE(sniffer1.is_chrome());
149 EXPECT_EQ(SniffData::OTHER, sniffer2.renderer_type());
150 EXPECT_EQ(small_html_meta_tag.size(), sniffer1.size());
151 EXPECT_EQ(small_html_no_meta_tag.size(), sniffer2.size());
152 }
153
154 // Now test how the data is fed back the the bind status callback.
155 // case 1: callback reads data in 1 read
156 TEST_F(MonikerPatchTest, SniffDataPlayback1) {
157 std::string small_html_meta_tag;
158 ScopedComPtr<IStream> stream_with_meta;
159 SniffData sniffer;
160
161 EXPECT_TRUE(sniffer.InitializeCache(std::wstring()));
162 ASSERT_TRUE(ReadFileAsString(kSmallHtmlMetaTag, &small_html_meta_tag));
163 ASSERT_TRUE(StringToStream(small_html_meta_tag, stream_with_meta.Receive()));
164 EXPECT_HRESULT_SUCCEEDED(sniffer.ReadIntoCache(stream_with_meta, true));
165
166 CComObjectStackEx<MockBindStatusCallbackImpl> mock;
167 const CLIPFORMAT cf = 0xd0d0;
168 const DWORD flags = BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION;
169 const DWORD data_size = small_html_meta_tag.size();
170
171 DWORD read_size1 = data_size * 2;
172 scoped_ptr<char> read_buffer1(new char[read_size1]);
173 ZeroMemory(read_buffer1.get(), read_size1);
174
175 char read_buffer2[10] = {0};
176 DWORD read_size2 = sizeof(read_buffer2);
177 HRESULT ret1 = E_FAIL, ret2 = E_FAIL;
178
179 EXPECT_CALL(mock, OnDataAvailable(flags, data_size,
180 testing::Field(&FORMATETC::cfFormat, cf),
181 testing::Field(&STGMEDIUM::tymed, TYMED_ISTREAM)))
182 .WillOnce(testing::DoAll(
183 ReadStream(read_buffer1.get(), &read_size1, &ret1),
184 ReadStream(read_buffer2, &read_size2, &ret2),
185 Return(S_OK)));
186
187 EXPECT_HRESULT_SUCCEEDED(sniffer.DrainCache(&mock, flags, cf));
188
189 EXPECT_HRESULT_SUCCEEDED(ret1);
190 EXPECT_EQ(small_html_meta_tag, read_buffer1.get());
191 EXPECT_EQ(data_size, read_size1);
192
193 EXPECT_EQ(E_PENDING, ret2);
194 EXPECT_STREQ("", read_buffer2);
195 EXPECT_EQ(sizeof(read_buffer2), read_size2);
196 }
197
198 // case 2: callback reads data in 2 reads.
199 TEST_F(MonikerPatchTest, SniffDataPlayback2) {
200 std::string small_html_meta_tag;
201 ScopedComPtr<IStream> stream_with_meta;
202 SniffData sniffer;
203
204 EXPECT_TRUE(sniffer.InitializeCache(std::wstring()));
205 ASSERT_TRUE(ReadFileAsString(kSmallHtmlMetaTag, &small_html_meta_tag));
206 ASSERT_TRUE(StringToStream(small_html_meta_tag, stream_with_meta.Receive()));
207 EXPECT_HRESULT_SUCCEEDED(sniffer.ReadIntoCache(stream_with_meta, true));
208
209 CComObjectStackEx<MockBindStatusCallbackImpl> mock;
210 const CLIPFORMAT cf = 0xd0d0;
211 const DWORD flags = BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION;
212 const DWORD data_size = small_html_meta_tag.size();
213
214 DWORD read_size1 = data_size / 2; // First read is half the data.
215 DWORD read_size2 = data_size; // Second read, try to read past data.
216 scoped_ptr<char> read_buffer1(new char[read_size1]);
217 scoped_ptr<char> read_buffer2(new char[read_size2]);
218 ZeroMemory(read_buffer1.get(), read_size1);
219 ZeroMemory(read_buffer2.get(), read_size2);
220
221 char read_buffer3[10] = {0};
222 DWORD read_size3 = sizeof(read_buffer3);
223 HRESULT ret1 = E_FAIL, ret2 = E_FAIL, ret3 = E_FAIL;
224
225 EXPECT_CALL(mock, OnDataAvailable(flags, data_size,
226 testing::Field(&FORMATETC::cfFormat, cf),
227 testing::Field(&STGMEDIUM::tymed, TYMED_ISTREAM)))
228 .WillOnce(testing::DoAll(
229 ReadStream(read_buffer1.get(), &read_size1, &ret1),
230 ReadStream(read_buffer2.get(), &read_size2, &ret2),
231 ReadStream(read_buffer3, &read_size3, &ret3),
232 Return(S_OK)));
233
234 EXPECT_HRESULT_SUCCEEDED(sniffer.DrainCache(&mock, flags, cf));
235
236 EXPECT_HRESULT_SUCCEEDED(ret1);
237 EXPECT_HRESULT_SUCCEEDED(ret2);
238 EXPECT_EQ(data_size/2, read_size1);
239 EXPECT_EQ(data_size - read_size1, read_size2);
240
241 std::string data_read;
242 data_read.append(read_buffer1.get(), read_size1);
243 data_read.append(read_buffer2.get(), read_size2);
244 EXPECT_EQ(small_html_meta_tag, data_read);
245
246 EXPECT_EQ(E_PENDING, ret3);
247 EXPECT_STREQ("", read_buffer3);
248 EXPECT_EQ(sizeof(read_buffer3), read_size3);
249 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698