1// Copyright (c) 2012 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 "net/url_request/view_cache_helper.h"
6
7#include "base/pickle.h"
8#include "net/base/net_errors.h"
9#include "net/base/test_completion_callback.h"
10#include "net/disk_cache/disk_cache.h"
11#include "net/http/http_cache.h"
12#include "net/http/http_transaction_test_util.h"
13#include "net/url_request/url_request_context.h"
14#include "testing/gtest/include/gtest/gtest.h"
15
16namespace net {
17
18namespace {
19
20class TestURLRequestContext : public URLRequestContext {
21 public:
22  TestURLRequestContext();
23
24  virtual ~TestURLRequestContext() {
25    AssertNoURLRequests();
26  }
27
28  // Gets a pointer to the cache backend.
29  disk_cache::Backend* GetBackend();
30
31 private:
32  HttpCache cache_;
33};
34
35TestURLRequestContext::TestURLRequestContext()
36    : cache_(new MockNetworkLayer(), NULL,
37             HttpCache::DefaultBackend::InMemory(0)) {
38  set_http_transaction_factory(&cache_);
39}
40
41void WriteHeaders(disk_cache::Entry* entry, int flags,
42                  const std::string& data) {
43  if (data.empty())
44    return;
45
46  Pickle pickle;
47  pickle.WriteInt(flags | 1);  // Version 1.
48  pickle.WriteInt64(0);
49  pickle.WriteInt64(0);
50  pickle.WriteString(data);
51
52  scoped_refptr<WrappedIOBuffer> buf(new WrappedIOBuffer(
53      reinterpret_cast<const char*>(pickle.data())));
54  int len = static_cast<int>(pickle.size());
55
56  net::TestCompletionCallback cb;
57  int rv = entry->WriteData(0, 0, buf.get(), len, cb.callback(), true);
58  ASSERT_EQ(len, cb.GetResult(rv));
59}
60
61void WriteData(disk_cache::Entry* entry, int index, const std::string& data) {
62  if (data.empty())
63    return;
64
65  int len = data.length();
66  scoped_refptr<IOBuffer> buf(new IOBuffer(len));
67  memcpy(buf->data(), data.data(), data.length());
68
69  net::TestCompletionCallback cb;
70  int rv = entry->WriteData(index, 0, buf.get(), len, cb.callback(), true);
71  ASSERT_EQ(len, cb.GetResult(rv));
72}
73
74void WriteToEntry(disk_cache::Backend* cache, const std::string& key,
75                  const std::string& data0, const std::string& data1,
76                  const std::string& data2) {
77  net::TestCompletionCallback cb;
78  disk_cache::Entry* entry;
79  int rv = cache->CreateEntry(key, &entry, cb.callback());
80  rv = cb.GetResult(rv);
81  if (rv != OK) {
82    rv = cache->OpenEntry(key, &entry, cb.callback());
83    ASSERT_EQ(OK, cb.GetResult(rv));
84  }
85
86  WriteHeaders(entry, 0, data0);
87  WriteData(entry, 1, data1);
88  WriteData(entry, 2, data2);
89
90  entry->Close();
91}
92
93void FillCache(URLRequestContext* context) {
94  net::TestCompletionCallback cb;
95  disk_cache::Backend* cache;
96  int rv =
97      context->http_transaction_factory()->GetCache()->GetBackend(
98          &cache, cb.callback());
99  ASSERT_EQ(OK, cb.GetResult(rv));
100
101  std::string empty;
102  WriteToEntry(cache, "first", "some", empty, empty);
103  WriteToEntry(cache, "second", "only hex_dumped", "same", "kind");
104  WriteToEntry(cache, "third", empty, "another", "thing");
105}
106
107}  // namespace.
108
109TEST(ViewCacheHelper, EmptyCache) {
110  TestURLRequestContext context;
111  ViewCacheHelper helper;
112
113  TestCompletionCallback cb;
114  std::string prefix, data;
115  int rv = helper.GetContentsHTML(&context, prefix, &data, cb.callback());
116  EXPECT_EQ(OK, cb.GetResult(rv));
117  EXPECT_FALSE(data.empty());
118}
119
120TEST(ViewCacheHelper, ListContents) {
121  TestURLRequestContext context;
122  ViewCacheHelper helper;
123
124  FillCache(&context);
125
126  std::string prefix, data;
127  TestCompletionCallback cb;
128  int rv = helper.GetContentsHTML(&context, prefix, &data, cb.callback());
129  EXPECT_EQ(OK, cb.GetResult(rv));
130
131  EXPECT_EQ(0U, data.find("<html>"));
132  EXPECT_NE(std::string::npos, data.find("</html>"));
133  EXPECT_NE(std::string::npos, data.find("first"));
134  EXPECT_NE(std::string::npos, data.find("second"));
135  EXPECT_NE(std::string::npos, data.find("third"));
136
137  EXPECT_EQ(std::string::npos, data.find("some"));
138  EXPECT_EQ(std::string::npos, data.find("same"));
139  EXPECT_EQ(std::string::npos, data.find("thing"));
140}
141
142TEST(ViewCacheHelper, DumpEntry) {
143  TestURLRequestContext context;
144  ViewCacheHelper helper;
145
146  FillCache(&context);
147
148  std::string data;
149  TestCompletionCallback cb;
150  int rv = helper.GetEntryInfoHTML("second", &context, &data, cb.callback());
151  EXPECT_EQ(OK, cb.GetResult(rv));
152
153  EXPECT_EQ(0U, data.find("<html>"));
154  EXPECT_NE(std::string::npos, data.find("</html>"));
155
156  EXPECT_NE(std::string::npos, data.find("hex_dumped"));
157  EXPECT_NE(std::string::npos, data.find("same"));
158  EXPECT_NE(std::string::npos, data.find("kind"));
159
160  EXPECT_EQ(std::string::npos, data.find("first"));
161  EXPECT_EQ(std::string::npos, data.find("third"));
162  EXPECT_EQ(std::string::npos, data.find("some"));
163  EXPECT_EQ(std::string::npos, data.find("another"));
164}
165
166// Makes sure the links are correct.
167TEST(ViewCacheHelper, Prefix) {
168  TestURLRequestContext context;
169  ViewCacheHelper helper;
170
171  FillCache(&context);
172
173  std::string key, data;
174  std::string prefix("prefix:");
175  TestCompletionCallback cb;
176  int rv = helper.GetContentsHTML(&context, prefix, &data, cb.callback());
177  EXPECT_EQ(OK, cb.GetResult(rv));
178
179  EXPECT_EQ(0U, data.find("<html>"));
180  EXPECT_NE(std::string::npos, data.find("</html>"));
181  EXPECT_NE(std::string::npos, data.find("<a href=\"prefix:first\">"));
182  EXPECT_NE(std::string::npos, data.find("<a href=\"prefix:second\">"));
183  EXPECT_NE(std::string::npos, data.find("<a href=\"prefix:third\">"));
184}
185
186TEST(ViewCacheHelper, TruncatedFlag) {
187  TestURLRequestContext context;
188  ViewCacheHelper helper;
189
190  net::TestCompletionCallback cb;
191  disk_cache::Backend* cache;
192  int rv =
193      context.http_transaction_factory()->GetCache()->GetBackend(
194          &cache, cb.callback());
195  ASSERT_EQ(OK, cb.GetResult(rv));
196
197  std::string key("the key");
198  disk_cache::Entry* entry;
199  rv = cache->CreateEntry(key, &entry, cb.callback());
200  ASSERT_EQ(OK, cb.GetResult(rv));
201
202  // RESPONSE_INFO_TRUNCATED defined on response_info.cc
203  int flags = 1 << 12;
204  WriteHeaders(entry, flags, "something");
205  entry->Close();
206
207  std::string data;
208  TestCompletionCallback cb1;
209  rv = helper.GetEntryInfoHTML(key, &context, &data, cb1.callback());
210  EXPECT_EQ(OK, cb1.GetResult(rv));
211
212  EXPECT_NE(std::string::npos, data.find("RESPONSE_INFO_TRUNCATED"));
213}
214
215}  // namespace net
216