[M120][Tizen][Onscreen] Fix build errors for TV profile
[platform/framework/web/chromium-efl.git] / chrome / browser / referrer_policy_browsertest.cc
1 // Copyright 2012 The Chromium Authors
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 <memory>
6
7 #include "base/command_line.h"
8 #include "base/functional/bind.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/synchronization/lock.h"
13 #include "base/thread_annotations.h"
14 #include "build/build_config.h"
15 #include "build/chromeos_buildflags.h"
16 #include "chrome/app/chrome_command_ids.h"
17 #include "chrome/browser/browser_process.h"
18 #include "chrome/browser/net/system_network_context_manager.h"
19 #include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
20 #include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h"
21 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/browser_commands.h"
23 #include "chrome/browser/ui/tabs/tab_strip_model.h"
24 #include "chrome/common/chrome_features.h"
25 #include "chrome/common/pref_names.h"
26 #include "chrome/test/base/in_process_browser_test.h"
27 #include "chrome/test/base/ui_test_utils.h"
28 #include "components/prefs/pref_service.h"
29 #include "content/public/browser/browser_thread.h"
30 #include "content/public/browser/navigation_controller.h"
31 #include "content/public/browser/navigation_entry.h"
32 #include "content/public/browser/render_view_host.h"
33 #include "content/public/browser/render_widget_host.h"
34 #include "content/public/browser/storage_partition.h"
35 #include "content/public/browser/web_contents.h"
36 #include "content/public/common/content_features.h"
37 #include "content/public/test/browser_test.h"
38 #include "content/public/test/browser_test_utils.h"
39 #include "net/base/features.h"
40 #include "net/test/embedded_test_server/http_request.h"
41 #include "services/network/public/mojom/referrer_policy.mojom-shared.h"
42 #include "third_party/blink/public/common/features.h"
43 #include "third_party/blink/public/common/input/web_input_event.h"
44 #include "third_party/blink/public/common/input/web_mouse_event.h"
45 #include "third_party/blink/public/common/loader/referrer_utils.h"
46 #include "third_party/blink/public/common/switches.h"
47 #include "ui/base/page_transition_types.h"
48 #include "ui/base/window_open_disposition.h"
49
50 class ReferrerPolicyTest : public InProcessBrowserTest {
51  public:
52   ReferrerPolicyTest() : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
53     // Subclasses might want to verify the requests that arrive at servers;
54     // register a default no-op handler that subclasses may override.
55     embedded_test_server()->RegisterRequestMonitor(base::BindRepeating(
56         &ReferrerPolicyTest::OnServerIncomingRequest, base::Unretained(this)));
57     https_server_.RegisterRequestMonitor(base::BindRepeating(
58         &ReferrerPolicyTest::OnServerIncomingRequest, base::Unretained(this)));
59
60     https_server_.AddDefaultHandlers(GetChromeTestDataDir());
61     EXPECT_TRUE(embedded_test_server()->Start());
62     EXPECT_TRUE(https_server_.Start());
63   }
64   ~ReferrerPolicyTest() override = default;
65
66   enum ExpectedReferrer {
67     EXPECT_EMPTY_REFERRER,
68     EXPECT_FULL_REFERRER,
69     EXPECT_ORIGIN_AS_REFERRER
70   };
71
72   void SetUpCommandLine(base::CommandLine* command_line) override {
73     // Some builders are flaky due to slower loading interacting
74     // with deferred commits.
75     command_line->AppendSwitch(blink::switches::kAllowPreCommitInput);
76   }
77
78  protected:
79   // Callback to verify that HTTP requests have the correct headers;
80   // currently, (See the comment on RequestCheck, below.)
81   virtual void OnServerIncomingRequest(
82       const net::test_server::HttpRequest& request) {
83     base::AutoLock lock(check_on_requests_lock_);
84     if (!check_on_requests_)
85       return;
86
87     if (request.relative_url != check_on_requests_->destination_url_to_match)
88       return;
89
90     auto it = request.headers.find("Referer");
91
92     if (check_on_requests_->expected_spec.empty()) {
93       EXPECT_TRUE(it == request.headers.end()) << it->second;
94     } else {
95       EXPECT_TRUE(it != request.headers.end());
96       if (it != request.headers.end())
97         EXPECT_EQ(it->second, check_on_requests_->expected_spec);
98     }
99   }
100
101   // Returns the expected title for the tab with the given (full) referrer and
102   // the expected modification of it.
103   std::u16string GetExpectedTitle(const GURL& url,
104                                   ExpectedReferrer expected_referrer) {
105     std::string referrer;
106     switch (expected_referrer) {
107       case EXPECT_EMPTY_REFERRER:
108         referrer = "Referrer is empty";
109         break;
110       case EXPECT_FULL_REFERRER:
111         referrer = "Referrer is " + url.spec();
112         break;
113       case EXPECT_ORIGIN_AS_REFERRER:
114         referrer = "Referrer is " + url.GetWithEmptyPath().spec();
115         break;
116     }
117     return base::ASCIIToUTF16(referrer);
118   }
119
120   // Adds all possible titles to the TitleWatcher, so we don't time out
121   // waiting for the title if the test fails.
122   void AddAllPossibleTitles(const GURL& url,
123                             content::TitleWatcher* title_watcher) {
124     title_watcher->AlsoWaitForTitle(
125         GetExpectedTitle(url, EXPECT_EMPTY_REFERRER));
126     title_watcher->AlsoWaitForTitle(
127         GetExpectedTitle(url, EXPECT_FULL_REFERRER));
128     title_watcher->AlsoWaitForTitle(
129         GetExpectedTitle(url, EXPECT_ORIGIN_AS_REFERRER));
130   }
131
132   enum StartOnProtocol { START_ON_HTTP, START_ON_HTTPS, };
133
134   enum LinkType { REGULAR_LINK, LINK_WITH_TARGET_BLANK, };
135
136   enum RedirectType {
137     NO_REDIRECT,        // direct navigation via HTTP
138     HTTPS_NO_REDIRECT,  // direct navigation via HTTPS
139     SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
140     SERVER_REDIRECT_FROM_HTTP_TO_HTTP,
141     SERVER_REDIRECT_FROM_HTTP_TO_HTTPS
142   };
143
144   enum RendererOrBrowserInitiated { RENDERER_INITIATED, BROWSER_INITIATED };
145
146   // Navigates from a page with a given |referrer_policy| and checks that the
147   // reported referrer matches the expectation.
148   // Parameters:
149   //  referrer_policy:   The referrer policy to test.
150   //  start_protocol:    The protocol the test should start on.
151   //  link_type:         The link type that is used to trigger the navigation.
152   //  redirect:          Whether the link target should redirect and how.
153   //  disposition:       The disposition for the navigation.
154   //  button:            If not WebMouseEvent::Button::NoButton, click on the
155   //                     link with the specified mouse button.
156   //  expected_referrer: The kind of referrer to expect.
157   //  expected_referrer_policy: The expected referrer policy of the activity.
158   //  renderer_or_browser_initiated: If BROWSER_INITIATED, uses Navigate() to
159   //  load in the current WebContents and disregards the value of |button|.
160   //
161   // Returns:
162   //  The URL of the first page navigated to.
163   GURL RunReferrerTest(const network::mojom::ReferrerPolicy referrer_policy,
164                        StartOnProtocol start_protocol,
165                        LinkType link_type,
166                        RedirectType redirect,
167                        WindowOpenDisposition disposition,
168                        blink::WebMouseEvent::Button button,
169                        ExpectedReferrer expected_referrer,
170                        network::mojom::ReferrerPolicy expected_referrer_policy,
171                        RendererOrBrowserInitiated
172                            renderer_or_browser_initiated = RENDERER_INITIATED) {
173     GURL redirect_url;
174     switch (redirect) {
175       case NO_REDIRECT:
176         redirect_url = embedded_test_server()->GetURL(
177             "/referrer_policy/referrer-policy-log.html");
178         break;
179       case HTTPS_NO_REDIRECT:
180         redirect_url =
181             https_server_.GetURL("/referrer_policy/referrer-policy-log.html");
182         break;
183       case SERVER_REDIRECT_FROM_HTTPS_TO_HTTP:
184         redirect_url = https_server_.GetURL(
185             std::string("/server-redirect?") +
186             embedded_test_server()
187                 ->GetURL("/referrer_policy/referrer-policy-log.html")
188                 .spec());
189         break;
190       case SERVER_REDIRECT_FROM_HTTP_TO_HTTP:
191         redirect_url = embedded_test_server()->GetURL(
192             std::string("/server-redirect?") +
193             embedded_test_server()
194                 ->GetURL("/referrer_policy/referrer-policy-log.html")
195                 .spec());
196         break;
197       case SERVER_REDIRECT_FROM_HTTP_TO_HTTPS:
198         redirect_url = embedded_test_server()->GetURL(
199             std::string("/server-redirect?") +
200             https_server_.GetURL("/referrer_policy/referrer-policy-log.html")
201                 .spec());
202         break;
203     }
204
205     std::string relative_url =
206         std::string("/referrer_policy/referrer-policy-start.html?") +
207         "policy=" + content::ReferrerPolicyToString(referrer_policy) +
208         "&redirect=" + redirect_url.spec() + "&link=" +
209         ((button == blink::WebMouseEvent::Button::kNoButton &&
210           renderer_or_browser_initiated == RENDERER_INITIATED)
211              ? "false"
212              : "true") +
213         "&target=" + (link_type == LINK_WITH_TARGET_BLANK ? "_blank" : "");
214
215     auto* start_test_server = start_protocol == START_ON_HTTPS
216                                   ? &https_server_
217                                   : embedded_test_server();
218     const GURL start_url = start_test_server->GetURL(relative_url);
219
220     ui_test_utils::AllBrowserTabAddedWaiter add_tab;
221
222     std::u16string expected_title =
223         GetExpectedTitle(start_url, expected_referrer);
224     content::WebContents* tab =
225         browser()->tab_strip_model()->GetActiveWebContents();
226     content::TitleWatcher title_watcher(tab, expected_title);
227
228     std::string expected_referrer_value;
229     if (expected_referrer != EXPECT_EMPTY_REFERRER) {
230       expected_referrer_value =
231           base::UTF16ToASCII(expected_title)
232               .substr(base::StringPiece("Referrer is ").size());
233     }
234     base::ReleasableAutoLock releaseable_lock(&check_on_requests_lock_);
235     check_on_requests_ = RequestCheck{
236         expected_referrer_value, "/referrer_policy/referrer-policy-log.html"};
237     releaseable_lock.Release();
238
239     // Watch for all possible outcomes to avoid timeouts if something breaks.
240     AddAllPossibleTitles(start_url, &title_watcher);
241
242     EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), start_url));
243
244     if (renderer_or_browser_initiated == BROWSER_INITIATED) {
245       CHECK(disposition == WindowOpenDisposition::CURRENT_TAB);
246       NavigateParams params(browser(), redirect_url, ui::PAGE_TRANSITION_LINK);
247       params.referrer = content::Referrer(
248           tab->GetController().GetVisibleEntry()->GetURL(), referrer_policy);
249       params.source_contents = tab;
250       ui_test_utils::NavigateToURL(&params);
251     } else if (button != blink::WebMouseEvent::Button::kNoButton) {
252       blink::WebMouseEvent mouse_event(
253           blink::WebInputEvent::Type::kMouseDown,
254           blink::WebInputEvent::kNoModifiers,
255           blink::WebInputEvent::GetStaticTimeStampForTests());
256       mouse_event.button = button;
257       mouse_event.SetPositionInWidget(15, 15);
258       mouse_event.click_count = 1;
259       tab->GetPrimaryMainFrame()
260           ->GetRenderViewHost()
261           ->GetWidget()
262           ->ForwardMouseEvent(mouse_event);
263       mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
264       tab->GetPrimaryMainFrame()
265           ->GetRenderViewHost()
266           ->GetWidget()
267           ->ForwardMouseEvent(mouse_event);
268     }
269
270     if (disposition == WindowOpenDisposition::CURRENT_TAB) {
271       EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
272     } else {
273       tab = add_tab.Wait();
274       EXPECT_TRUE(tab);
275       content::TitleWatcher title_watcher2(tab, expected_title);
276
277       // Watch for all possible outcomes to avoid timeouts if something breaks.
278       AddAllPossibleTitles(start_url, &title_watcher2);
279
280       EXPECT_EQ(expected_title, title_watcher2.WaitAndGetTitle());
281     }
282
283     EXPECT_EQ(expected_referrer_policy,
284               tab->GetController().GetVisibleEntry()->GetReferrer().policy);
285
286     base::AutoLock lock(check_on_requests_lock_);
287     check_on_requests_.reset();
288
289     return start_url;
290   }
291
292   // Shorthand for cases where |referrer_policy| is the expected policy.
293   GURL RunReferrerTest(const network::mojom::ReferrerPolicy referrer_policy,
294                        StartOnProtocol start_protocol,
295                        LinkType link_type,
296                        RedirectType redirect,
297                        WindowOpenDisposition disposition,
298                        blink::WebMouseEvent::Button button,
299                        ExpectedReferrer expected_referrer) {
300     return RunReferrerTest(referrer_policy, start_protocol, link_type, redirect,
301                            disposition, button, expected_referrer,
302                            referrer_policy);
303   }
304
305   net::EmbeddedTestServer https_server_;
306
307   // If "check_on_requests_" is set, for each HTTP request that arrives at
308   // either of the embedded test servers ("embedded_test_server()" and
309   // "https_server_"), if the relative URL equals that stored in
310   // "destination_url_to_match", OnServerIncomingRequest will assert
311   // that the provided Referer header's value equals the value of
312   // "expected_spec".
313   struct RequestCheck {
314     std::string expected_spec;
315     std::string destination_url_to_match;
316   };
317
318   base::Lock check_on_requests_lock_;
319   absl::optional<RequestCheck> check_on_requests_
320       GUARDED_BY(check_on_requests_lock_);
321 };
322
323 // The basic behavior of referrer policies is covered by layout tests in
324 // http/tests/security/referrer-policy-*. These tests cover (hopefully) all
325 // code paths chrome uses to navigate. To keep the number of combinations down,
326 // we only test the "origin" policy here.
327
328 // Content initiated navigation, from HTTP to HTTP.
329 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, Origin) {
330   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
331                   REGULAR_LINK, NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
332                   blink::WebMouseEvent::Button::kNoButton,
333                   EXPECT_ORIGIN_AS_REFERRER);
334 }
335
336 // Content initiated navigation, from HTTPS to HTTP.
337 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsDefault) {
338   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
339                   REGULAR_LINK, NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
340                   blink::WebMouseEvent::Button::kNoButton,
341                   EXPECT_ORIGIN_AS_REFERRER);
342 }
343
344 // User initiated navigation, from HTTP to HTTP.
345 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, LeftClickOrigin) {
346   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
347                   REGULAR_LINK, NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
348                   blink::WebMouseEvent::Button::kLeft,
349                   EXPECT_ORIGIN_AS_REFERRER);
350 }
351
352 // User initiated navigation, from HTTPS to HTTP.
353 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsLeftClickOrigin) {
354   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
355                   REGULAR_LINK, NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
356                   blink::WebMouseEvent::Button::kLeft,
357                   EXPECT_ORIGIN_AS_REFERRER);
358 }
359
360 // User initiated navigation, middle click, from HTTP to HTTP.
361 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickOrigin) {
362   RunReferrerTest(
363       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP, REGULAR_LINK,
364       NO_REDIRECT, WindowOpenDisposition::NEW_BACKGROUND_TAB,
365       blink::WebMouseEvent::Button::kMiddle, EXPECT_ORIGIN_AS_REFERRER);
366 }
367
368 // User initiated navigation, middle click, from HTTPS to HTTP.
369 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickOrigin) {
370   RunReferrerTest(
371       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS, REGULAR_LINK,
372       NO_REDIRECT, WindowOpenDisposition::NEW_BACKGROUND_TAB,
373       blink::WebMouseEvent::Button::kMiddle, EXPECT_ORIGIN_AS_REFERRER);
374 }
375
376 // User initiated navigation, target blank, from HTTP to HTTP.
377 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, TargetBlankOrigin) {
378   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
379                   LINK_WITH_TARGET_BLANK, NO_REDIRECT,
380                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
381                   blink::WebMouseEvent::Button::kLeft,
382                   EXPECT_ORIGIN_AS_REFERRER);
383 }
384
385 // User initiated navigation, target blank, from HTTPS to HTTP.
386 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsTargetBlankOrigin) {
387   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
388                   LINK_WITH_TARGET_BLANK, NO_REDIRECT,
389                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
390                   blink::WebMouseEvent::Button::kLeft,
391                   EXPECT_ORIGIN_AS_REFERRER);
392 }
393
394 // User initiated navigation, middle click, target blank, from HTTP to HTTP.
395 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickTargetBlankOrigin) {
396   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
397                   LINK_WITH_TARGET_BLANK, NO_REDIRECT,
398                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
399                   blink::WebMouseEvent::Button::kMiddle,
400                   EXPECT_ORIGIN_AS_REFERRER);
401 }
402
403 // User initiated navigation, middle click, target blank, from HTTPS to HTTP.
404 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickTargetBlankOrigin) {
405   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
406                   LINK_WITH_TARGET_BLANK, NO_REDIRECT,
407                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
408                   blink::WebMouseEvent::Button::kMiddle,
409                   EXPECT_ORIGIN_AS_REFERRER);
410 }
411
412 // Context menu, from HTTP to HTTP.
413 // TODO(crbug.com/1269942): Flaky on Lacros.
414 #if BUILDFLAG(IS_CHROMEOS_LACROS)
415 #define MAYBE_ContextMenuOrigin DISABLED_ContextMenuOrigin
416 #else
417 #define MAYBE_ContextMenuOrigin ContextMenuOrigin
418 #endif
419 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MAYBE_ContextMenuOrigin) {
420   ContextMenuNotificationObserver context_menu_observer(
421       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
422   RunReferrerTest(
423       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP, REGULAR_LINK,
424       NO_REDIRECT, WindowOpenDisposition::NEW_FOREGROUND_TAB,
425       blink::WebMouseEvent::Button::kRight, EXPECT_ORIGIN_AS_REFERRER);
426 }
427
428 // Context menu, from HTTPS to HTTP.
429 // TODO(crbug.com/1269041): Fix flakiness on Linux and Lacros then reenable.
430 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
431 #define MAYBE_HttpsContextMenuOrigin DISABLED_HttpsContextMenuOrigin
432 #else
433 #define MAYBE_HttpsContextMenuOrigin HttpsContextMenuOrigin
434 #endif
435 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MAYBE_HttpsContextMenuOrigin) {
436   ContextMenuNotificationObserver context_menu_observer(
437       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
438   RunReferrerTest(
439       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS, REGULAR_LINK,
440       NO_REDIRECT, WindowOpenDisposition::NEW_FOREGROUND_TAB,
441       blink::WebMouseEvent::Button::kRight, EXPECT_ORIGIN_AS_REFERRER);
442 }
443
444 // Content initiated navigation, from HTTP to HTTP via server redirect.
445 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, Redirect) {
446   RunReferrerTest(
447       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP, REGULAR_LINK,
448       SERVER_REDIRECT_FROM_HTTPS_TO_HTTP, WindowOpenDisposition::CURRENT_TAB,
449       blink::WebMouseEvent::Button::kNoButton, EXPECT_ORIGIN_AS_REFERRER);
450 }
451
452 // Content initiated navigation, from HTTPS to HTTP via server redirect.
453 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsRedirect) {
454   RunReferrerTest(
455       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS, REGULAR_LINK,
456       SERVER_REDIRECT_FROM_HTTPS_TO_HTTP, WindowOpenDisposition::CURRENT_TAB,
457       blink::WebMouseEvent::Button::kNoButton, EXPECT_ORIGIN_AS_REFERRER);
458 }
459
460 // User initiated navigation, from HTTP to HTTP via server redirect.
461 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, LeftClickRedirect) {
462   RunReferrerTest(
463       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP, REGULAR_LINK,
464       SERVER_REDIRECT_FROM_HTTP_TO_HTTP, WindowOpenDisposition::CURRENT_TAB,
465       blink::WebMouseEvent::Button::kLeft, EXPECT_ORIGIN_AS_REFERRER);
466 }
467
468 // User initiated navigation, from HTTPS to HTTP via server redirect.
469 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsLeftClickRedirect) {
470   RunReferrerTest(
471       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS, REGULAR_LINK,
472       SERVER_REDIRECT_FROM_HTTPS_TO_HTTP, WindowOpenDisposition::CURRENT_TAB,
473       blink::WebMouseEvent::Button::kLeft, EXPECT_ORIGIN_AS_REFERRER);
474 }
475
476 // User initiated navigation, middle click, from HTTP to HTTP via server
477 // redirect.
478 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickRedirect) {
479   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
480                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
481                   WindowOpenDisposition::NEW_BACKGROUND_TAB,
482                   blink::WebMouseEvent::Button::kMiddle,
483                   EXPECT_ORIGIN_AS_REFERRER);
484 }
485
486 // User initiated navigation, middle click, from HTTPS to HTTP via server
487 // redirect.
488 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickRedirect) {
489   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
490                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
491                   WindowOpenDisposition::NEW_BACKGROUND_TAB,
492                   blink::WebMouseEvent::Button::kMiddle,
493                   EXPECT_ORIGIN_AS_REFERRER);
494 }
495
496 // User initiated navigation, target blank, from HTTP to HTTP via server
497 // redirect.
498 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, TargetBlankRedirect) {
499   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
500                   LINK_WITH_TARGET_BLANK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
501                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
502                   blink::WebMouseEvent::Button::kLeft,
503                   EXPECT_ORIGIN_AS_REFERRER);
504 }
505
506 // User initiated navigation, target blank, from HTTPS to HTTP via server
507 // redirect.
508 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsTargetBlankRedirect) {
509   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
510                   LINK_WITH_TARGET_BLANK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
511                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
512                   blink::WebMouseEvent::Button::kLeft,
513                   EXPECT_ORIGIN_AS_REFERRER);
514 }
515
516 // User initiated navigation, middle click, target blank, from HTTP to HTTP via
517 // server redirect.
518 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickTargetBlankRedirect) {
519   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
520                   LINK_WITH_TARGET_BLANK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
521                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
522                   blink::WebMouseEvent::Button::kMiddle,
523                   EXPECT_ORIGIN_AS_REFERRER);
524 }
525
526 // User initiated navigation, middle click, target blank, from HTTPS to HTTP
527 // via server redirect.
528 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
529                        HttpsMiddleClickTargetBlankRedirect) {
530   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
531                   LINK_WITH_TARGET_BLANK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
532                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
533                   blink::WebMouseEvent::Button::kMiddle,
534                   EXPECT_ORIGIN_AS_REFERRER);
535 }
536
537 // Context menu, from HTTP to HTTP via server redirect.
538 // TODO(crbug.com/1269041): Fix flakiness on Linux and Lacros then reenable.
539 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
540 #define MAYBE_ContextMenuRedirect DISABLED_ContextMenuRedirect
541 #else
542 #define MAYBE_ContextMenuRedirect ContextMenuRedirect
543 #endif
544 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MAYBE_ContextMenuRedirect) {
545   ContextMenuNotificationObserver context_menu_observer(
546       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
547   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
548                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
549                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
550                   blink::WebMouseEvent::Button::kRight,
551                   EXPECT_ORIGIN_AS_REFERRER);
552 }
553
554 // Context menu, from HTTPS to HTTP via server redirect.
555 // TODO(crbug.com/1269942): Flaky on Lacros.
556 #if BUILDFLAG(IS_CHROMEOS_LACROS)
557 #define MAYBE_HttpsContextMenuRedirect DISABLED_HttpsContextMenuRedirect
558 #else
559 #define MAYBE_HttpsContextMenuRedirect HttpsContextMenuRedirect
560 #endif
561 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MAYBE_HttpsContextMenuRedirect) {
562   ContextMenuNotificationObserver context_menu_observer(
563       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
564   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
565                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
566                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
567                   blink::WebMouseEvent::Button::kRight,
568                   EXPECT_ORIGIN_AS_REFERRER);
569 }
570
571 // Tests history navigation actions: Navigate from A to B with a referrer
572 // policy, then navigate to C, back to B, and reload.
573 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, History) {
574   // Navigate from A to B.
575   GURL start_url = RunReferrerTest(
576       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS, REGULAR_LINK,
577       SERVER_REDIRECT_FROM_HTTPS_TO_HTTP, WindowOpenDisposition::CURRENT_TAB,
578       blink::WebMouseEvent::Button::kLeft, EXPECT_ORIGIN_AS_REFERRER);
579
580   // Navigate to C.
581   ASSERT_TRUE(ui_test_utils::NavigateToURL(
582       browser(), embedded_test_server()->GetURL("/title1.html")));
583
584   std::u16string expected_title =
585       GetExpectedTitle(start_url, EXPECT_ORIGIN_AS_REFERRER);
586   content::WebContents* tab =
587       browser()->tab_strip_model()->GetActiveWebContents();
588   std::unique_ptr<content::TitleWatcher> title_watcher(
589       new content::TitleWatcher(tab, expected_title));
590
591   // Watch for all possible outcomes to avoid timeouts if something breaks.
592   AddAllPossibleTitles(start_url, title_watcher.get());
593
594   // Go back to B.
595   chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB);
596   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
597
598   title_watcher = std::make_unique<content::TitleWatcher>(tab, expected_title);
599   AddAllPossibleTitles(start_url, title_watcher.get());
600
601   // Reload to B.
602   chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
603   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
604
605   title_watcher = std::make_unique<content::TitleWatcher>(tab, expected_title);
606   AddAllPossibleTitles(start_url, title_watcher.get());
607
608   // Shift-reload to B.
609   chrome::ReloadBypassingCache(browser(), WindowOpenDisposition::CURRENT_TAB);
610   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
611 }
612
613 // Tests that reloading a site for "request tablet version" correctly clears
614 // the referrer.
615 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, RequestTabletSite) {
616   GURL start_url = RunReferrerTest(
617       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS, REGULAR_LINK,
618       SERVER_REDIRECT_FROM_HTTP_TO_HTTP, WindowOpenDisposition::CURRENT_TAB,
619       blink::WebMouseEvent::Button::kLeft, EXPECT_ORIGIN_AS_REFERRER);
620
621   std::u16string expected_title =
622       GetExpectedTitle(start_url, EXPECT_EMPTY_REFERRER);
623   content::WebContents* tab =
624       browser()->tab_strip_model()->GetActiveWebContents();
625   content::TitleWatcher title_watcher(tab, expected_title);
626
627   // Watch for all possible outcomes to avoid timeouts if something breaks.
628   AddAllPossibleTitles(start_url, &title_watcher);
629
630   // Erase the current title in the NavigationEntry.
631   //
632   // TitleWatcher overrides WebContentObserver's TitleWasSet() but also
633   // DidStopLoading(). The page that is being reloaded sets its title after load
634   // is complete, so the title change is missed because the title is checked on
635   // load. Clearing the title ensures that TitleWatcher will wait for the actual
636   // title setting.
637   tab->GetController().GetVisibleEntry()->SetTitle(std::u16string());
638
639   // Request tablet version.
640   chrome::ToggleRequestTabletSite(browser());
641   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
642 }
643
644 // Test that an iframes gets the parent frames referrer and referrer policy if
645 // the load was triggered by the parent, or from the iframe itself, if the
646 // navigations was started by the iframe.
647 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, IFrame) {
648   browser()->profile()->GetPrefs()->SetBoolean(
649       prefs::kWebKitAllowRunningInsecureContent, true);
650   content::WebContents* tab =
651       browser()->tab_strip_model()->GetActiveWebContents();
652   std::u16string expected_title(u"loaded");
653   std::unique_ptr<content::TitleWatcher> title_watcher(
654       new content::TitleWatcher(tab, expected_title));
655
656   // Load a page that loads an iframe.
657   ASSERT_TRUE(ui_test_utils::NavigateToURL(
658       browser(),
659       https_server_.GetURL("/referrer_policy/referrer-policy-iframe.html")));
660   EXPECT_TRUE(content::ExecJs(
661       tab,
662       std::string("var frame = document.createElement('iframe');frame.src ='") +
663           embedded_test_server()
664               ->GetURL("/referrer_policy/referrer-policy-log.html")
665               .spec() +
666           "';frame.onload = function() { document.title = 'loaded'; };" +
667           "document.body.appendChild(frame)"));
668   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
669
670   // Verify that the referrer policy was honored and the main page's origin was
671   // send as referrer.
672   content::RenderFrameHost* frame = content::FrameMatchingPredicate(
673       tab->GetPrimaryPage(),
674       base::BindRepeating(&content::FrameIsChildOfMainFrame));
675   std::string title = content::EvalJs(frame, "document.title").ExtractString();
676   EXPECT_EQ("Referrer is " + https_server_.GetURL("/").spec(), title);
677
678   // Reload the iframe.
679   expected_title = u"reset";
680   title_watcher = std::make_unique<content::TitleWatcher>(tab, expected_title);
681   EXPECT_TRUE(content::ExecJs(tab, "document.title = 'reset'"));
682   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
683   frame = content::FrameMatchingPredicate(
684       tab->GetPrimaryPage(),
685       base::BindRepeating(&content::FrameIsChildOfMainFrame));
686
687   expected_title = u"loaded";
688   title_watcher = std::make_unique<content::TitleWatcher>(tab, expected_title);
689   EXPECT_TRUE(content::ExecJs(frame, "location.reload()"));
690   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
691   frame = content::FrameMatchingPredicate(
692       tab->GetPrimaryPage(),
693       base::BindRepeating(&content::FrameIsChildOfMainFrame));
694
695   // Verify that the full url of the iframe was used as referrer.
696   title = content::EvalJs(frame, "document.title").ExtractString();
697   EXPECT_EQ(
698       "Referrer is " + embedded_test_server()
699                            ->GetURL("/referrer_policy/referrer-policy-log.html")
700                            .spec(),
701       title);
702 }
703
704 // Origin When Cross-Origin
705
706 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
707                        HttpLeftClickHTTPSRedirectToHTTPOriginWhenCrossOrigin) {
708   RunReferrerTest(
709       network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, START_ON_HTTPS,
710       REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
711       WindowOpenDisposition::CURRENT_TAB, blink::WebMouseEvent::Button::kLeft,
712       EXPECT_ORIGIN_AS_REFERRER);
713 }
714
715 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
716                        HttpLeftClickRedirectToHTTPSOriginWhenCrossOrigin) {
717   RunReferrerTest(
718       network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, START_ON_HTTP,
719       REGULAR_LINK, SERVER_REDIRECT_FROM_HTTP_TO_HTTPS,
720       WindowOpenDisposition::CURRENT_TAB, blink::WebMouseEvent::Button::kLeft,
721       EXPECT_ORIGIN_AS_REFERRER);
722 }
723
724 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
725                        HttpLeftClickRedirectToHTTPOriginWhenCrossOrigin) {
726   RunReferrerTest(network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin,
727                   START_ON_HTTP, REGULAR_LINK,
728                   SERVER_REDIRECT_FROM_HTTP_TO_HTTP,
729                   WindowOpenDisposition::CURRENT_TAB,
730                   blink::WebMouseEvent::Button::kLeft, EXPECT_FULL_REFERRER);
731 }
732
733 // Same origin
734
735 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
736                        HttpLeftClickHTTPRedirectToHTTPSameOrigin) {
737   RunReferrerTest(network::mojom::ReferrerPolicy::kSameOrigin, START_ON_HTTP,
738                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTP_TO_HTTP,
739                   WindowOpenDisposition::CURRENT_TAB,
740                   blink::WebMouseEvent::Button::kLeft, EXPECT_FULL_REFERRER);
741 }
742
743 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
744                        HttpLeftClickHTTPRedirectToHTTPSSameOrigin) {
745   RunReferrerTest(network::mojom::ReferrerPolicy::kSameOrigin, START_ON_HTTPS,
746                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
747                   WindowOpenDisposition::CURRENT_TAB,
748                   blink::WebMouseEvent::Button::kLeft, EXPECT_EMPTY_REFERRER);
749 }
750
751 // Strict origin
752
753 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
754                        HttpLeftClickHTTPRedirectToHTTPStrictOrigin) {
755   RunReferrerTest(network::mojom::ReferrerPolicy::kStrictOrigin, START_ON_HTTP,
756                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTP_TO_HTTP,
757                   WindowOpenDisposition::CURRENT_TAB,
758                   blink::WebMouseEvent::Button::kLeft,
759                   EXPECT_ORIGIN_AS_REFERRER);
760 }
761
762 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
763                        HttpLeftClickHTTPSRedirectToHTTPStrictOrigin) {
764   RunReferrerTest(network::mojom::ReferrerPolicy::kStrictOrigin, START_ON_HTTPS,
765                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
766                   WindowOpenDisposition::CURRENT_TAB,
767                   blink::WebMouseEvent::Button::kLeft, EXPECT_EMPTY_REFERRER);
768 }
769
770 // Parameters for testing functionality imposing ad-hoc restrictions
771 // on the behavior of referrers, for instance absolute caps like
772 // "never send referrers" (as of writing, features::kNoReferrers)
773 // or "on cross-origin requests, never send more than the initiator's
774 // origin" (features::kCapReferrerToOriginOnCrossOrigin).
775 //
776 // These tests assume a default policy of no-referrer-when-downgrade.
777 struct ReferrerOverrideParams {
778   absl::optional<base::test::FeatureRef> feature_to_enable;
779   network::mojom::ReferrerPolicy baseline_policy;
780   network::mojom::ReferrerPolicy expected_policy;
781
782   ReferrerPolicyTest::ExpectedReferrer same_origin_nav,  // HTTP -> HTTP
783       cross_origin_nav,                                  // HTTP -> HTTP
784       cross_origin_downgrade_nav,  // HTTPS -> HTTP, cross-origin
785       same_origin_to_cross_origin_redirect,
786       cross_origin_to_same_origin_redirect, same_origin_subresource,
787       same_origin_to_cross_origin_subresource_redirect;
788 } kReferrerOverrideParams[] = {
789     {.feature_to_enable = features::kNoReferrers,
790      .baseline_policy = network::mojom::ReferrerPolicy::kAlways,
791      // The renderer's "have we completely disabled referrers?"
792      // implementation resets requests' referrer policies to kNever when
793      // it excises their referrers.
794      .expected_policy = network::mojom::ReferrerPolicy::kNever,
795      .same_origin_nav = ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
796      .cross_origin_nav = ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
797      .cross_origin_downgrade_nav = ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
798      .same_origin_to_cross_origin_redirect =
799          ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
800      .cross_origin_to_same_origin_redirect =
801          ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
802      .same_origin_subresource = ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
803      .same_origin_to_cross_origin_subresource_redirect =
804          ReferrerPolicyTest::EXPECT_EMPTY_REFERRER},
805     {
806         .feature_to_enable = net::features::kCapReferrerToOriginOnCrossOrigin,
807         .baseline_policy = network::mojom::ReferrerPolicy::kAlways,
808         // Applying the cap doesn't change the "referrer policy"
809         // attribute of a request
810         .expected_policy = network::mojom::ReferrerPolicy::kAlways,
811         .same_origin_nav = ReferrerPolicyTest::EXPECT_FULL_REFERRER,
812         .cross_origin_nav = ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
813         .cross_origin_downgrade_nav =
814             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
815         .same_origin_to_cross_origin_redirect =
816             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
817         // Referrer policies get applied to whatever the current referrer is:
818         // in the case of a cross-origin -> same-origin redirect, we already
819         // will have truncated the referrer to the initiating origin
820         .cross_origin_to_same_origin_redirect =
821             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
822         .same_origin_subresource = ReferrerPolicyTest::EXPECT_FULL_REFERRER,
823         .same_origin_to_cross_origin_subresource_redirect =
824             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
825     },
826     {
827         .baseline_policy = network::mojom::ReferrerPolicy::kDefault,
828         // kDefault gets resolved into a concrete policy when making requests
829         .expected_policy =
830             network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin,
831         .same_origin_nav = ReferrerPolicyTest::EXPECT_FULL_REFERRER,
832         .cross_origin_nav = ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
833         .cross_origin_downgrade_nav = ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
834         .same_origin_to_cross_origin_redirect =
835             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
836         .cross_origin_to_same_origin_redirect =
837             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
838         .same_origin_subresource = ReferrerPolicyTest::EXPECT_FULL_REFERRER,
839         .same_origin_to_cross_origin_subresource_redirect =
840             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
841     }};
842
843 class ReferrerOverrideTest
844     : public ReferrerPolicyTest,
845       public ::testing::WithParamInterface<ReferrerOverrideParams> {
846  public:
847   ReferrerOverrideTest() {
848     if (GetParam().feature_to_enable) {
849       scoped_feature_list_.InitAndEnableFeature(
850           *GetParam().feature_to_enable.value());
851     }
852   }
853
854  protected:
855   // Test that the correct referrer is sent along with
856   // a subresource request.
857   // Parameter semantics are the same as for
858   // ReferrerPolicyTest::RunReferrerTest.
859   void RunSubresourceTest(StartOnProtocol start_protocol,
860                           RedirectType redirect,
861                           network::mojom::ReferrerPolicy baseline_policy,
862                           ExpectedReferrer expectation) {
863     GURL image_url;
864     switch (redirect) {
865       case NO_REDIRECT:
866         image_url = embedded_test_server()->GetURL("/referrer_policy/logo.gif");
867         break;
868       case HTTPS_NO_REDIRECT:
869         image_url = https_server_.GetURL("/referrer_policy/logo.gif");
870         break;
871       case SERVER_REDIRECT_FROM_HTTPS_TO_HTTP:
872         image_url = https_server_.GetURL(
873             std::string("/server-redirect?") +
874             embedded_test_server()->GetURL("/referrer_policy/logo.gif").spec());
875         break;
876       case SERVER_REDIRECT_FROM_HTTP_TO_HTTP:
877         image_url = embedded_test_server()->GetURL(
878             std::string("/server-redirect?") +
879             embedded_test_server()->GetURL("/referrer_policy/logo.gif").spec());
880         break;
881       case SERVER_REDIRECT_FROM_HTTP_TO_HTTPS:
882         image_url = embedded_test_server()->GetURL(
883             std::string("/server-redirect?") +
884             https_server_.GetURL("/referrer_policy/logo.gif").spec());
885         break;
886     }
887
888     std::string relative_url =
889         std::string("/referrer_policy/referrer-policy-subresource.html?") +
890         "policy=" + content::ReferrerPolicyToString(baseline_policy) +
891         "&redirect=" + image_url.spec();
892
893     auto* start_server = start_protocol == START_ON_HTTPS
894                              ? &https_server_
895                              : embedded_test_server();
896     const GURL start_url = start_server->GetURL(relative_url);
897
898     content::WebContents* tab =
899         browser()->tab_strip_model()->GetActiveWebContents();
900
901     base::ReleasableAutoLock lock(&check_on_requests_lock_);
902     check_on_requests_ = RequestCheck{"", "/referrer_policy/logo.gif"};
903     switch (expectation) {
904       case ReferrerPolicyTest::EXPECT_EMPTY_REFERRER:
905         check_on_requests_->expected_spec = "";
906         break;
907       case ReferrerPolicyTest::EXPECT_FULL_REFERRER:
908         check_on_requests_->expected_spec = start_url.spec();
909         break;
910       case ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER:
911         check_on_requests_->expected_spec = start_url.GetWithEmptyPath().spec();
912         break;
913     }
914     lock.Release();
915
916     // set by referrer-policy-subresource.html JS after the embedded image loads
917     std::u16string expected_title(u"loaded");
918     std::unique_ptr<content::TitleWatcher> title_watcher(
919         new content::TitleWatcher(tab, expected_title));
920     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), start_url));
921
922     // Wait for the page to load; during the load, since check_on_requests_ is
923     // nonempty, OnServerIncomingRequest will validate the referrers.
924     EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
925   }
926
927  private:
928   base::test::ScopedFeatureList scoped_feature_list_;
929 };
930
931 INSTANTIATE_TEST_SUITE_P(
932     WithOverrideParams,
933     ReferrerOverrideTest,
934     ::testing::ValuesIn(kReferrerOverrideParams),
935     [](const ::testing::TestParamInfo<ReferrerOverrideParams>& info)
936         -> std::string {
937       if (info.param.feature_to_enable) {
938         return base::StringPrintf("Param%s",
939                                   info.param.feature_to_enable.value()->name);
940       }
941       return "NoFeature";
942     });
943
944 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, SameOriginNavigation) {
945   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTP, REGULAR_LINK,
946                   NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
947                   blink::WebMouseEvent::Button::kNoButton,
948                   GetParam().same_origin_nav, GetParam().expected_policy);
949 }
950
951 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, CrossOriginNavigation) {
952   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTP, REGULAR_LINK,
953                   HTTPS_NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
954                   blink::WebMouseEvent::Button::kNoButton,
955                   GetParam().cross_origin_nav, GetParam().expected_policy);
956 }
957
958 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest,
959                        CrossOriginNavigationBrowserInitiated) {
960   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTP, REGULAR_LINK,
961                   HTTPS_NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
962                   blink::WebMouseEvent::Button::kLeft,
963                   GetParam().cross_origin_nav, GetParam().expected_policy,
964                   BROWSER_INITIATED);
965 }
966
967 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, CrossOriginDowngradeNavigation) {
968   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTPS, REGULAR_LINK,
969                   NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
970                   blink::WebMouseEvent::Button::kNoButton,
971                   GetParam().cross_origin_downgrade_nav,
972                   GetParam().expected_policy);
973 }
974
975 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, CrossOriginRedirect) {
976   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTP, REGULAR_LINK,
977                   SERVER_REDIRECT_FROM_HTTP_TO_HTTPS,
978                   WindowOpenDisposition::CURRENT_TAB,
979                   blink::WebMouseEvent::Button::kNoButton,
980                   GetParam().same_origin_to_cross_origin_redirect,
981                   GetParam().expected_policy);
982 }
983
984 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, CrossOriginToSameOriginRedirect) {
985   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTP, REGULAR_LINK,
986                   SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
987                   WindowOpenDisposition::CURRENT_TAB,
988                   blink::WebMouseEvent::Button::kNoButton,
989                   GetParam().cross_origin_to_same_origin_redirect,
990                   GetParam().expected_policy);
991 }
992
993 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, SameOriginSubresource) {
994   RunSubresourceTest(START_ON_HTTP, NO_REDIRECT, GetParam().baseline_policy,
995                      GetParam().same_origin_subresource);
996 }
997
998 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest,
999                        SameOriginToCrossOriginSubresourceRedirect) {
1000   RunSubresourceTest(
1001       START_ON_HTTP, SERVER_REDIRECT_FROM_HTTP_TO_HTTPS,
1002       GetParam().baseline_policy,
1003       GetParam().same_origin_to_cross_origin_subresource_redirect);
1004 }
1005
1006 // Most of the functionality of the referrer-cap flag is covered by
1007 // ReferrerOverrideTest; these couple additional tests test the flag's
1008 // interaction with other referrer policies
1009 class ReferrerPolicyCapReferrerToOriginOnCrossOriginTest
1010     : public ReferrerPolicyTest {
1011  public:
1012   ReferrerPolicyCapReferrerToOriginOnCrossOriginTest() {
1013     scoped_feature_list_.InitAndEnableFeature(
1014         net::features::kCapReferrerToOriginOnCrossOrigin);
1015   }
1016
1017  private:
1018   base::test::ScopedFeatureList scoped_feature_list_;
1019 };
1020
1021 // Test that capping referrer granularity at origin on cross-origin requests
1022 // correctly defers to a more restrictive referrer policy on a
1023 // cross-origin navigation.
1024 IN_PROC_BROWSER_TEST_F(ReferrerPolicyCapReferrerToOriginOnCrossOriginTest,
1025                        HonorsMoreRestrictivePolicyOnNavigation) {
1026   RunReferrerTest(network::mojom::ReferrerPolicy::kSameOrigin, START_ON_HTTPS,
1027                   REGULAR_LINK, NO_REDIRECT /*direct navigation x-origin*/,
1028                   WindowOpenDisposition::CURRENT_TAB,
1029                   blink::WebMouseEvent::Button::kLeft, EXPECT_EMPTY_REFERRER);
1030 }
1031
1032 // Test that capping referrer granularity at origin on cross-origin requests
1033 // correctly defers to a more restrictive referrer policy on a
1034 // cross-origin redirect.
1035 IN_PROC_BROWSER_TEST_F(ReferrerPolicyCapReferrerToOriginOnCrossOriginTest,
1036                        HonorsMoreRestrictivePolicyOnRedirect) {
1037   RunReferrerTest(network::mojom::ReferrerPolicy::kStrictOrigin, START_ON_HTTPS,
1038                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
1039                   WindowOpenDisposition::CURRENT_TAB,
1040                   blink::WebMouseEvent::Button::kLeft, EXPECT_EMPTY_REFERRER);
1041 }
1042
1043 // Test that, when the cross-origin referrer cap is on but we also have the
1044 // "no referrers at all" pref set, we send no referrer at all on cross-origin
1045 // requests.
1046 IN_PROC_BROWSER_TEST_F(ReferrerPolicyCapReferrerToOriginOnCrossOriginTest,
1047                        RespectsNoReferrerPref) {
1048   browser()->profile()->GetPrefs()->SetBoolean(prefs::kEnableReferrers, false);
1049   browser()
1050       ->profile()
1051       ->GetDefaultStoragePartition()
1052       ->FlushNetworkInterfaceForTesting();
1053   RunReferrerTest(network::mojom::ReferrerPolicy::kAlways, START_ON_HTTPS,
1054                   REGULAR_LINK, NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
1055                   blink::WebMouseEvent::Button::kLeft, EXPECT_EMPTY_REFERRER,
1056                   // when the pref is set, the renderer sets the referrer policy
1057                   // to the kNever on outgoing requests at the same time
1058                   // it removes referrers
1059                   network::mojom::ReferrerPolicy::kNever);
1060 }