1731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_util.h"
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/path_service.h"
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/stringprintf.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h"
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "googleurl/src/gurl.h"
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_errors.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log_unittest.h"
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_info.h"
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_resolver_js_bindings.h"
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_resolver_v8.h"
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h"
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net {
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Javascript bindings for ProxyResolverV8, which returns mock values.
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Each time one of the bindings is called into, we push the input into a
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// list, for later verification.
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MockJSBindings : public ProxyResolverJSBindings {
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockJSBindings() : my_ip_address_count(0), my_ip_address_ex_count(0) {}
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Alert(const string16& message) {
29731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    VLOG(1) << "PAC-alert: " << message;  // Helpful when debugging.
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    alerts.push_back(UTF16ToUTF8(message));
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool MyIpAddress(std::string* ip_address) {
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    my_ip_address_count++;
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *ip_address = my_ip_address_result;
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return !my_ip_address_result.empty();
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool MyIpAddressEx(std::string* ip_address_list) {
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    my_ip_address_ex_count++;
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *ip_address_list = my_ip_address_ex_result;
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return !my_ip_address_ex_result.empty();
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool DnsResolve(const std::string& host, std::string* ip_address) {
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    dns_resolves.push_back(host);
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *ip_address = dns_resolve_result;
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return !dns_resolve_result.empty();
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool DnsResolveEx(const std::string& host,
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            std::string* ip_address_list) {
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    dns_resolves_ex.push_back(host);
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *ip_address_list = dns_resolve_ex_result;
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return !dns_resolve_ex_result.empty();
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnError(int line_number, const string16& message) {
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Helpful when debugging.
60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    VLOG(1) << "PAC-error: [" << line_number << "] " << message;
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    errors.push_back(UTF16ToUTF8(message));
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    errors_line_number.push_back(line_number);
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Shutdown() {}
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Mock values to return.
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string my_ip_address_result;
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string my_ip_address_ex_result;
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string dns_resolve_result;
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string dns_resolve_ex_result;
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Inputs we got called with.
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::vector<std::string> alerts;
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::vector<std::string> errors;
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::vector<int> errors_line_number;
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::vector<std::string> dns_resolves;
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::vector<std::string> dns_resolves_ex;
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int my_ip_address_count;
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int my_ip_address_ex_count;
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This is the same as ProxyResolverV8, but it uses mock bindings in place of
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// the default bindings, and has a helper function to load PAC scripts from
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// disk.
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ProxyResolverV8WithMockBindings : public ProxyResolverV8 {
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyResolverV8WithMockBindings() : ProxyResolverV8(new MockJSBindings()) {}
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockJSBindings* mock_js_bindings() const {
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return reinterpret_cast<MockJSBindings*>(js_bindings());
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Initialize with the PAC script data at |filename|.
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int SetPacScriptFromDisk(const char* filename) {
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    FilePath path;
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    PathService::Get(base::DIR_SOURCE_ROOT, &path);
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    path = path.AppendASCII("net");
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    path = path.AppendASCII("data");
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    path = path.AppendASCII("proxy_resolver_v8_unittest");
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    path = path.AppendASCII(filename);
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Try to read the file from disk.
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string file_contents;
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bool ok = file_util::ReadFileToString(path, &file_contents);
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // If we can't load the file from disk, something is misconfigured.
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!ok) {
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      LOG(ERROR) << "Failed to read file: " << path.value();
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return ERR_UNEXPECTED;
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Load the PAC script into the ProxyResolver.
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return SetPacScript(ProxyResolverScriptData::FromUTF8(file_contents),
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        NULL);
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Doesn't really matter what these values are for many of the tests.
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst GURL kQueryUrl("http://www.google.com");
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst GURL kPacUrl;
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyResolverV8Test, Direct) {
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyResolverV8WithMockBindings resolver;
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int result = resolver.SetPacScriptFromDisk("direct.js");
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo proxy_info;
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   log.bound());
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(proxy_info.is_direct());
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  net::CapturingNetLog::EntryList entries;
14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  log.GetEntries(&entries);
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // No bindings were called, so no log entries.
14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(0u, entries.size());
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyResolverV8Test, ReturnEmptyString) {
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyResolverV8WithMockBindings resolver;
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int result = resolver.SetPacScriptFromDisk("return_empty_string.js");
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo proxy_info;
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(proxy_info.is_direct());
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyResolverV8Test, Basic) {
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyResolverV8WithMockBindings resolver;
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int result = resolver.SetPacScriptFromDisk("passthrough.js");
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The "FindProxyForURL" of this PAC script simply concatenates all of the
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // arguments into a pseudo-host. The purpose of this test is to verify that
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the correct arguments are being passed to FindProxyForURL().
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ProxyInfo proxy_info;
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    result = resolver.GetProxyForURL(GURL("http://query.com/path"),
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     &proxy_info, NULL, NULL, BoundNetLog());
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(OK, result);
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ("http.query.com.path.query.com:80",
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              proxy_info.proxy_server().ToURI());
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ProxyInfo proxy_info;
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int result = resolver.GetProxyForURL(GURL("ftp://query.com:90/path"),
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         &proxy_info, NULL, NULL,
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         BoundNetLog());
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(OK, result);
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Note that FindProxyForURL(url, host) does not expect |host| to contain
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // the port number.
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ("ftp.query.com.90.path.query.com:80",
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              proxy_info.proxy_server().ToURI());
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We call this so we'll have code coverage of the function and valgrind will
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // make sure nothing bad happens.
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // NOTE: This is here instead of in its own test so that we'll be calling it
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // after having done something, in hopes it won't be a no-op.
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver.PurgeMemory();
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyResolverV8Test, BadReturnType) {
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // These are the filenames of PAC scripts which each return a non-string
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // types for FindProxyForURL(). They should all fail with
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // ERR_PAC_SCRIPT_FAILED.
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const char* const filenames[] = {
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "return_undefined.js",
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "return_integer.js",
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "return_function.js",
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "return_object.js",
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // TODO(eroman): Should 'null' be considered equivalent to "DIRECT" ?
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "return_null.js"
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (size_t i = 0; i < arraysize(filenames); ++i) {
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ProxyResolverV8WithMockBindings resolver;
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int result = resolver.SetPacScriptFromDisk(filenames[i]);
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(OK, result);
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ProxyInfo proxy_info;
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     BoundNetLog());
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    MockJSBindings* bindings = resolver.mock_js_bindings();
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(0U, bindings->alerts.size());
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ASSERT_EQ(1U, bindings->errors.size());
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ("FindProxyForURL() did not return a string.",
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              bindings->errors[0]);
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(-1, bindings->errors_line_number[0]);
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Try using a PAC script which defines no "FindProxyForURL" function.
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyResolverV8Test, NoEntryPoint) {
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyResolverV8WithMockBindings resolver;
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int result = resolver.SetPacScriptFromDisk("no_entrypoint.js");
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo proxy_info;
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_FAILED, result);
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Try loading a malformed PAC script.
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyResolverV8Test, ParseError) {
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyResolverV8WithMockBindings resolver;
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int result = resolver.SetPacScriptFromDisk("missing_close_brace.js");
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo proxy_info;
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_FAILED, result);
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockJSBindings* bindings = resolver.mock_js_bindings();
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0U, bindings->alerts.size());
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We get one error during compilation.
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1U, bindings->errors.size());
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("Uncaught SyntaxError: Unexpected end of input",
267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            bindings->errors[0]);
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, bindings->errors_line_number[0]);
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Run a PAC script several times, which has side-effects.
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyResolverV8Test, SideEffects) {
273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyResolverV8WithMockBindings resolver;
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int result = resolver.SetPacScriptFromDisk("side_effects.js");
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The PAC script increments a counter each time we invoke it.
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < 3; ++i) {
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ProxyInfo proxy_info;
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     BoundNetLog());
281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(OK, result);
2823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(base::StringPrintf("sideffect_%d:80", i),
283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              proxy_info.proxy_server().ToURI());
284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Reload the script -- the javascript environment should be reset, hence
287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the counter starts over.
288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  result = resolver.SetPacScriptFromDisk("side_effects.js");
289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < 3; ++i) {
292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ProxyInfo proxy_info;
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     BoundNetLog());
295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(OK, result);
2963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(base::StringPrintf("sideffect_%d:80", i),
297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              proxy_info.proxy_server().ToURI());
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Execute a PAC script which throws an exception in FindProxyForURL.
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyResolverV8Test, UnhandledException) {
303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyResolverV8WithMockBindings resolver;
304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int result = resolver.SetPacScriptFromDisk("unhandled_exception.js");
305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo proxy_info;
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockJSBindings* bindings = resolver.mock_js_bindings();
314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0U, bindings->alerts.size());
315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1U, bindings->errors.size());
316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("Uncaught ReferenceError: undefined_variable is not defined",
317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            bindings->errors[0]);
318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(3, bindings->errors_line_number[0]);
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(ProxyResolverV8Test, ReturnUnicode) {
322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyResolverV8WithMockBindings resolver;
323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int result = resolver.SetPacScriptFromDisk("return_unicode.js");
324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo proxy_info;
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The result from this resolve was unparseable, because it
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // wasn't ASCII.
332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);
333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test the PAC library functions that we expose in the JS environmnet.
336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyResolverV8Test, JavascriptLibrary) {
337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyResolverV8WithMockBindings resolver;
338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int result = resolver.SetPacScriptFromDisk("pac_library_unittest.js");
339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo proxy_info;
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // If the javascript side of this unit-test fails, it will throw a javascript
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // exception. Otherwise it will return "PROXY success:80".
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("success:80", proxy_info.proxy_server().ToURI());
349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Try resolving when SetPacScriptByData() has not been called.
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyResolverV8Test, NoSetPacScript) {
356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyResolverV8WithMockBindings resolver;
357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo proxy_info;
359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Resolve should fail, as we are not yet initialized with a script.
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       BoundNetLog());
363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_FAILED, result);
364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Initialize it.
366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  result = resolver.SetPacScriptFromDisk("direct.js");
367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Resolve should now succeed.
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Clear it, by initializing with an empty string.
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  resolver.SetPacScript(
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ProxyResolverScriptData::FromUTF16(string16()), NULL);
377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Resolve should fail again now.
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_FAILED, result);
382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Load a good script once more.
384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  result = resolver.SetPacScriptFromDisk("direct.js");
385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test marshalling/un-marshalling of values between C++/V8.
395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyResolverV8Test, V8Bindings) {
396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyResolverV8WithMockBindings resolver;
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockJSBindings* bindings = resolver.mock_js_bindings();
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bindings->dns_resolve_result = "127.0.0.1";
399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int result = resolver.SetPacScriptFromDisk("bindings.js");
400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo proxy_info;
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(proxy_info.is_direct());
408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Alert was called 5 times.
412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(5U, bindings->alerts.size());
413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("undefined", bindings->alerts[0]);
414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("null", bindings->alerts[1]);
415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("undefined", bindings->alerts[2]);
416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("[object Object]", bindings->alerts[3]);
417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("exception from calling toString()", bindings->alerts[4]);
418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // DnsResolve was called 8 times, however only 2 of those were string
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // parameters. (so 6 of them failed immediately).
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(2U, bindings->dns_resolves.size());
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("", bindings->dns_resolves[0]);
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("arg1", bindings->dns_resolves[1]);
424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // MyIpAddress was called two times.
426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, bindings->my_ip_address_count);
427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // MyIpAddressEx was called once.
429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, bindings->my_ip_address_ex_count);
430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // DnsResolveEx was called 2 times.
432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(2U, bindings->dns_resolves_ex.size());
433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("is_resolvable", bindings->dns_resolves_ex[0]);
434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foobar", bindings->dns_resolves_ex[1]);
435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test calling a binding (myIpAddress()) from the script's global scope.
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// http://crbug.com/40026
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(ProxyResolverV8Test, BindingCalledDuringInitialization) {
440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyResolverV8WithMockBindings resolver;
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int result = resolver.SetPacScriptFromDisk("binding_from_global.js");
443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockJSBindings* bindings = resolver.mock_js_bindings();
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // myIpAddress() got called during initialization of the script.
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, bindings->my_ip_address_count);
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo proxy_info;
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(proxy_info.is_direct());
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("127.0.0.1:80", proxy_info.proxy_server().ToURI());
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check that no other bindings were called.
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0U, bindings->errors.size());
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(0U, bindings->alerts.size());
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(0U, bindings->dns_resolves.size());
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, bindings->my_ip_address_ex_count);
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(0U, bindings->dns_resolves_ex.size());
464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Try loading a PAC script that ends with a comment and has no terminal
467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// newline. This should not cause problems with the PAC utility functions
468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// that we add to the script's environment.
469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// http://crbug.com/22864
470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyResolverV8Test, EndsWithCommentNoNewline) {
471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyResolverV8WithMockBindings resolver;
472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int result = resolver.SetPacScriptFromDisk("ends_with_comment.js");
473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo proxy_info;
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   log.bound());
479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(proxy_info.is_direct());
482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("success:80", proxy_info.proxy_server().ToURI());
483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Try loading a PAC script that ends with a statement and has no terminal
486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// newline. This should not cause problems with the PAC utility functions
487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// that we add to the script's environment.
488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// http://crbug.com/22864
489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyResolverV8Test, EndsWithStatementNoNewline) {
490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyResolverV8WithMockBindings resolver;
491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int result = resolver.SetPacScriptFromDisk(
492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "ends_with_statement_no_semicolon.js");
493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo proxy_info;
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   log.bound());
499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(proxy_info.is_direct());
502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("success:3", proxy_info.proxy_server().ToURI());
503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test the return values from myIpAddress(), myIpAddressEx(), dnsResolve(),
506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// dnsResolveEx(), isResolvable(), isResolvableEx(), when the the binding
507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// returns empty string (failure). This simulates the return values from
508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// those functions when the underlying DNS resolution fails.
509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyResolverV8Test, DNSResolutionFailure) {
510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyResolverV8WithMockBindings resolver;
511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int result = resolver.SetPacScriptFromDisk("dns_fail.js");
512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo proxy_info;
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, result);
519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(proxy_info.is_direct());
520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("success:80", proxy_info.proxy_server().ToURI());
521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(ProxyResolverV8Test, DNSResolutionOfInternationDomainName) {
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProxyResolverV8WithMockBindings resolver;
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int result = resolver.SetPacScriptFromDisk("international_domain_names.js");
526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, result);
527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Execute FindProxyForURL().
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProxyInfo proxy_info;
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, result);
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(proxy_info.is_direct());
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check that the international domain name was converted to punycode
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // before passing it onto the bindings layer.
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockJSBindings* bindings = resolver.mock_js_bindings();
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, bindings->dns_resolves.size());
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("xn--bcher-kva.ch", bindings->dns_resolves[0]);
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, bindings->dns_resolves_ex.size());
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("xn--bcher-kva.ch", bindings->dns_resolves_ex[0]);
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace
548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace net
549