[M94 Dev] Remove *.pyc files from git repositories
[platform/framework/web/chromium-efl.git] / chrome / browser / referrer_policy_browsertest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <memory>
6
7 #include "base/bind.h"
8 #include "base/command_line.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 "chrome/app/chrome_command_ids.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/net/system_network_context_manager.h"
18 #include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
19 #include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h"
20 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/browser_commands.h"
22 #include "chrome/browser/ui/tabs/tab_strip_model.h"
23 #include "chrome/common/chrome_features.h"
24 #include "chrome/common/pref_names.h"
25 #include "chrome/test/base/in_process_browser_test.h"
26 #include "chrome/test/base/ui_test_utils.h"
27 #include "components/prefs/pref_service.h"
28 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/navigation_controller.h"
30 #include "content/public/browser/navigation_entry.h"
31 #include "content/public/browser/notification_service.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     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->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
260           mouse_event);
261       mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp);
262       tab->GetMainFrame()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
263           mouse_event);
264     }
265
266     if (disposition == WindowOpenDisposition::CURRENT_TAB) {
267       EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
268     } else {
269       tab = add_tab.Wait();
270       EXPECT_TRUE(tab);
271       content::TitleWatcher title_watcher2(tab, expected_title);
272
273       // Watch for all possible outcomes to avoid timeouts if something breaks.
274       AddAllPossibleTitles(start_url, &title_watcher2);
275
276       EXPECT_EQ(expected_title, title_watcher2.WaitAndGetTitle());
277     }
278
279     EXPECT_EQ(expected_referrer_policy,
280               tab->GetController().GetVisibleEntry()->GetReferrer().policy);
281
282     base::AutoLock lock(check_on_requests_lock_);
283     check_on_requests_.reset();
284
285     return start_url;
286   }
287
288   // Shorthand for cases where |referrer_policy| is the expected policy.
289   GURL RunReferrerTest(const network::mojom::ReferrerPolicy referrer_policy,
290                        StartOnProtocol start_protocol,
291                        LinkType link_type,
292                        RedirectType redirect,
293                        WindowOpenDisposition disposition,
294                        blink::WebMouseEvent::Button button,
295                        ExpectedReferrer expected_referrer) {
296     return RunReferrerTest(referrer_policy, start_protocol, link_type, redirect,
297                            disposition, button, expected_referrer,
298                            referrer_policy);
299   }
300
301   net::EmbeddedTestServer https_server_;
302
303   // If "check_on_requests_" is set, for each HTTP request that arrives at
304   // either of the embedded test servers ("embedded_test_server()" and
305   // "https_server_"), if the relative URL equals that stored in
306   // "destination_url_to_match", OnServerIncomingRequest will assert
307   // that the provided Referer header's value equals the value of
308   // "expected_spec".
309   struct RequestCheck {
310     std::string expected_spec;
311     std::string destination_url_to_match;
312   };
313
314   base::Lock check_on_requests_lock_;
315   absl::optional<RequestCheck> check_on_requests_
316       GUARDED_BY(check_on_requests_lock_);
317 };
318
319 // The basic behavior of referrer policies is covered by layout tests in
320 // http/tests/security/referrer-policy-*. These tests cover (hopefully) all
321 // code paths chrome uses to navigate. To keep the number of combinations down,
322 // we only test the "origin" policy here.
323
324 // Content initiated navigation, from HTTP to HTTP.
325 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, Origin) {
326   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
327                   REGULAR_LINK, NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
328                   blink::WebMouseEvent::Button::kNoButton,
329                   EXPECT_ORIGIN_AS_REFERRER);
330 }
331
332 // Content initiated navigation, from HTTPS to HTTP.
333 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsDefault) {
334   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
335                   REGULAR_LINK, NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
336                   blink::WebMouseEvent::Button::kNoButton,
337                   EXPECT_ORIGIN_AS_REFERRER);
338 }
339
340 // User initiated navigation, from HTTP to HTTP.
341 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, LeftClickOrigin) {
342   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
343                   REGULAR_LINK, NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
344                   blink::WebMouseEvent::Button::kLeft,
345                   EXPECT_ORIGIN_AS_REFERRER);
346 }
347
348 // User initiated navigation, from HTTPS to HTTP.
349 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsLeftClickOrigin) {
350   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
351                   REGULAR_LINK, NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
352                   blink::WebMouseEvent::Button::kLeft,
353                   EXPECT_ORIGIN_AS_REFERRER);
354 }
355
356 // User initiated navigation, middle click, from HTTP to HTTP.
357 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickOrigin) {
358   RunReferrerTest(
359       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP, REGULAR_LINK,
360       NO_REDIRECT, WindowOpenDisposition::NEW_BACKGROUND_TAB,
361       blink::WebMouseEvent::Button::kMiddle, EXPECT_ORIGIN_AS_REFERRER);
362 }
363
364 // User initiated navigation, middle click, from HTTPS to HTTP.
365 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickOrigin) {
366   RunReferrerTest(
367       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS, REGULAR_LINK,
368       NO_REDIRECT, WindowOpenDisposition::NEW_BACKGROUND_TAB,
369       blink::WebMouseEvent::Button::kMiddle, EXPECT_ORIGIN_AS_REFERRER);
370 }
371
372 // User initiated navigation, target blank, from HTTP to HTTP.
373 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, TargetBlankOrigin) {
374   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
375                   LINK_WITH_TARGET_BLANK, NO_REDIRECT,
376                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
377                   blink::WebMouseEvent::Button::kLeft,
378                   EXPECT_ORIGIN_AS_REFERRER);
379 }
380
381 // User initiated navigation, target blank, from HTTPS to HTTP.
382 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsTargetBlankOrigin) {
383   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
384                   LINK_WITH_TARGET_BLANK, NO_REDIRECT,
385                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
386                   blink::WebMouseEvent::Button::kLeft,
387                   EXPECT_ORIGIN_AS_REFERRER);
388 }
389
390 // User initiated navigation, middle click, target blank, from HTTP to HTTP.
391 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickTargetBlankOrigin) {
392   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
393                   LINK_WITH_TARGET_BLANK, NO_REDIRECT,
394                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
395                   blink::WebMouseEvent::Button::kMiddle,
396                   EXPECT_ORIGIN_AS_REFERRER);
397 }
398
399 // User initiated navigation, middle click, target blank, from HTTPS to HTTP.
400 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickTargetBlankOrigin) {
401   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
402                   LINK_WITH_TARGET_BLANK, NO_REDIRECT,
403                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
404                   blink::WebMouseEvent::Button::kMiddle,
405                   EXPECT_ORIGIN_AS_REFERRER);
406 }
407
408 // Context menu, from HTTP to HTTP.
409 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, ContextMenuOrigin) {
410   ContextMenuNotificationObserver context_menu_observer(
411       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
412   RunReferrerTest(
413       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP, REGULAR_LINK,
414       NO_REDIRECT, WindowOpenDisposition::NEW_FOREGROUND_TAB,
415       blink::WebMouseEvent::Button::kRight, EXPECT_ORIGIN_AS_REFERRER);
416 }
417
418 // Context menu, from HTTPS to HTTP.
419 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsContextMenuOrigin) {
420   ContextMenuNotificationObserver context_menu_observer(
421       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
422   RunReferrerTest(
423       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS, REGULAR_LINK,
424       NO_REDIRECT, WindowOpenDisposition::NEW_FOREGROUND_TAB,
425       blink::WebMouseEvent::Button::kRight, EXPECT_ORIGIN_AS_REFERRER);
426 }
427
428 // Content initiated navigation, from HTTP to HTTP via server redirect.
429 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, Redirect) {
430   RunReferrerTest(
431       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP, REGULAR_LINK,
432       SERVER_REDIRECT_FROM_HTTPS_TO_HTTP, WindowOpenDisposition::CURRENT_TAB,
433       blink::WebMouseEvent::Button::kNoButton, EXPECT_ORIGIN_AS_REFERRER);
434 }
435
436 // Content initiated navigation, from HTTPS to HTTP via server redirect.
437 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsRedirect) {
438   RunReferrerTest(
439       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS, REGULAR_LINK,
440       SERVER_REDIRECT_FROM_HTTPS_TO_HTTP, WindowOpenDisposition::CURRENT_TAB,
441       blink::WebMouseEvent::Button::kNoButton, EXPECT_ORIGIN_AS_REFERRER);
442 }
443
444 // User initiated navigation, from HTTP to HTTP via server redirect.
445 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, LeftClickRedirect) {
446   RunReferrerTest(
447       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP, REGULAR_LINK,
448       SERVER_REDIRECT_FROM_HTTP_TO_HTTP, WindowOpenDisposition::CURRENT_TAB,
449       blink::WebMouseEvent::Button::kLeft, EXPECT_ORIGIN_AS_REFERRER);
450 }
451
452 // User initiated navigation, from HTTPS to HTTP via server redirect.
453 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsLeftClickRedirect) {
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::kLeft, EXPECT_ORIGIN_AS_REFERRER);
458 }
459
460 // User initiated navigation, middle click, from HTTP to HTTP via server
461 // redirect.
462 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickRedirect) {
463   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
464                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
465                   WindowOpenDisposition::NEW_BACKGROUND_TAB,
466                   blink::WebMouseEvent::Button::kMiddle,
467                   EXPECT_ORIGIN_AS_REFERRER);
468 }
469
470 // User initiated navigation, middle click, from HTTPS to HTTP via server
471 // redirect.
472 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsMiddleClickRedirect) {
473   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
474                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
475                   WindowOpenDisposition::NEW_BACKGROUND_TAB,
476                   blink::WebMouseEvent::Button::kMiddle,
477                   EXPECT_ORIGIN_AS_REFERRER);
478 }
479
480 // User initiated navigation, target blank, from HTTP to HTTP via server
481 // redirect.
482 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, TargetBlankRedirect) {
483   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
484                   LINK_WITH_TARGET_BLANK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
485                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
486                   blink::WebMouseEvent::Button::kLeft,
487                   EXPECT_ORIGIN_AS_REFERRER);
488 }
489
490 // User initiated navigation, target blank, from HTTPS to HTTP via server
491 // redirect.
492 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsTargetBlankRedirect) {
493   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
494                   LINK_WITH_TARGET_BLANK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
495                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
496                   blink::WebMouseEvent::Button::kLeft,
497                   EXPECT_ORIGIN_AS_REFERRER);
498 }
499
500 // User initiated navigation, middle click, target blank, from HTTP to HTTP via
501 // server redirect.
502 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, MiddleClickTargetBlankRedirect) {
503   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
504                   LINK_WITH_TARGET_BLANK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
505                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
506                   blink::WebMouseEvent::Button::kMiddle,
507                   EXPECT_ORIGIN_AS_REFERRER);
508 }
509
510 // User initiated navigation, middle click, target blank, from HTTPS to HTTP
511 // via server redirect.
512 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
513                        HttpsMiddleClickTargetBlankRedirect) {
514   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
515                   LINK_WITH_TARGET_BLANK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
516                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
517                   blink::WebMouseEvent::Button::kMiddle,
518                   EXPECT_ORIGIN_AS_REFERRER);
519 }
520
521 // Context menu, from HTTP to HTTP via server redirect.
522 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, ContextMenuRedirect) {
523   ContextMenuNotificationObserver context_menu_observer(
524       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
525   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTP,
526                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
527                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
528                   blink::WebMouseEvent::Button::kRight,
529                   EXPECT_ORIGIN_AS_REFERRER);
530 }
531
532 // Context menu, from HTTPS to HTTP via server redirect.
533 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, HttpsContextMenuRedirect) {
534   ContextMenuNotificationObserver context_menu_observer(
535       IDC_CONTENT_CONTEXT_OPENLINKNEWTAB);
536   RunReferrerTest(network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS,
537                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
538                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
539                   blink::WebMouseEvent::Button::kRight,
540                   EXPECT_ORIGIN_AS_REFERRER);
541 }
542
543 // Tests history navigation actions: Navigate from A to B with a referrer
544 // policy, then navigate to C, back to B, and reload.
545 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, History) {
546   // Navigate from A to B.
547   GURL start_url = RunReferrerTest(
548       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS, REGULAR_LINK,
549       SERVER_REDIRECT_FROM_HTTPS_TO_HTTP, WindowOpenDisposition::CURRENT_TAB,
550       blink::WebMouseEvent::Button::kLeft, EXPECT_ORIGIN_AS_REFERRER);
551
552   // Navigate to C.
553   ui_test_utils::NavigateToURL(browser(),
554                                embedded_test_server()->GetURL("/title1.html"));
555
556   std::u16string expected_title =
557       GetExpectedTitle(start_url, EXPECT_ORIGIN_AS_REFERRER);
558   content::WebContents* tab =
559       browser()->tab_strip_model()->GetActiveWebContents();
560   std::unique_ptr<content::TitleWatcher> title_watcher(
561       new content::TitleWatcher(tab, expected_title));
562
563   // Watch for all possible outcomes to avoid timeouts if something breaks.
564   AddAllPossibleTitles(start_url, title_watcher.get());
565
566   // Go back to B.
567   chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB);
568   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
569
570   title_watcher = std::make_unique<content::TitleWatcher>(tab, expected_title);
571   AddAllPossibleTitles(start_url, title_watcher.get());
572
573   // Reload to B.
574   chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
575   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
576
577   title_watcher = std::make_unique<content::TitleWatcher>(tab, expected_title);
578   AddAllPossibleTitles(start_url, title_watcher.get());
579
580   // Shift-reload to B.
581   chrome::ReloadBypassingCache(browser(), WindowOpenDisposition::CURRENT_TAB);
582   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
583 }
584
585 // Tests that reloading a site for "request tablet version" correctly clears
586 // the referrer.
587 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, RequestTabletSite) {
588   GURL start_url = RunReferrerTest(
589       network::mojom::ReferrerPolicy::kOrigin, START_ON_HTTPS, REGULAR_LINK,
590       SERVER_REDIRECT_FROM_HTTP_TO_HTTP, WindowOpenDisposition::CURRENT_TAB,
591       blink::WebMouseEvent::Button::kLeft, EXPECT_ORIGIN_AS_REFERRER);
592
593   std::u16string expected_title =
594       GetExpectedTitle(start_url, EXPECT_EMPTY_REFERRER);
595   content::WebContents* tab =
596       browser()->tab_strip_model()->GetActiveWebContents();
597   content::TitleWatcher title_watcher(tab, expected_title);
598
599   // Watch for all possible outcomes to avoid timeouts if something breaks.
600   AddAllPossibleTitles(start_url, &title_watcher);
601
602   // Erase the current title in the NavigationEntry.
603   //
604   // TitleWatcher overrides WebContentObserver's TitleWasSet() but also
605   // DidStopLoading(). The page that is being reloaded sets its title after load
606   // is complete, so the title change is missed because the title is checked on
607   // load. Clearing the title ensures that TitleWatcher will wait for the actual
608   // title setting.
609   tab->GetController().GetVisibleEntry()->SetTitle(std::u16string());
610
611   // Request tablet version.
612   chrome::ToggleRequestTabletSite(browser());
613   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
614 }
615
616 // Test that an iframes gets the parent frames referrer and referrer policy if
617 // the load was triggered by the parent, or from the iframe itself, if the
618 // navigations was started by the iframe.
619 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest, IFrame) {
620   browser()->profile()->GetPrefs()->SetBoolean(
621       prefs::kWebKitAllowRunningInsecureContent, true);
622   content::WebContents* tab =
623       browser()->tab_strip_model()->GetActiveWebContents();
624   std::u16string expected_title(u"loaded");
625   std::unique_ptr<content::TitleWatcher> title_watcher(
626       new content::TitleWatcher(tab, expected_title));
627
628   // Load a page that loads an iframe.
629   ui_test_utils::NavigateToURL(
630       browser(),
631       https_server_.GetURL("/referrer_policy/referrer-policy-iframe.html"));
632   EXPECT_TRUE(content::ExecuteScript(
633       tab,
634       std::string("var frame = document.createElement('iframe');frame.src ='") +
635           embedded_test_server()
636               ->GetURL("/referrer_policy/referrer-policy-log.html")
637               .spec() +
638           "';frame.onload = function() { document.title = 'loaded'; };" +
639           "document.body.appendChild(frame)"));
640   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
641
642   // Verify that the referrer policy was honored and the main page's origin was
643   // send as referrer.
644   content::RenderFrameHost* frame = content::FrameMatchingPredicate(
645       tab->GetPrimaryPage(),
646       base::BindRepeating(&content::FrameIsChildOfMainFrame));
647   std::string title;
648   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
649       frame,
650       "window.domAutomationController.send(document.title)",
651       &title));
652   EXPECT_EQ("Referrer is " + https_server_.GetURL("/").spec(), title);
653
654   // Reload the iframe.
655   expected_title = u"reset";
656   title_watcher = std::make_unique<content::TitleWatcher>(tab, expected_title);
657   EXPECT_TRUE(content::ExecuteScript(tab, "document.title = 'reset'"));
658   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
659
660   expected_title = u"loaded";
661   title_watcher = std::make_unique<content::TitleWatcher>(tab, expected_title);
662   EXPECT_TRUE(content::ExecuteScript(frame, "location.reload()"));
663   EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
664
665   // Verify that the full url of the iframe was used as referrer.
666   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
667       frame,
668       "window.domAutomationController.send(document.title)",
669       &title));
670   EXPECT_EQ(
671       "Referrer is " + embedded_test_server()
672                            ->GetURL("/referrer_policy/referrer-policy-log.html")
673                            .spec(),
674       title);
675 }
676
677 // Origin When Cross-Origin
678
679 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
680                        HttpLeftClickHTTPSRedirectToHTTPOriginWhenCrossOrigin) {
681   RunReferrerTest(
682       network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, START_ON_HTTPS,
683       REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
684       WindowOpenDisposition::CURRENT_TAB, blink::WebMouseEvent::Button::kLeft,
685       EXPECT_ORIGIN_AS_REFERRER);
686 }
687
688 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
689                        HttpLeftClickRedirectToHTTPSOriginWhenCrossOrigin) {
690   RunReferrerTest(
691       network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin, START_ON_HTTP,
692       REGULAR_LINK, SERVER_REDIRECT_FROM_HTTP_TO_HTTPS,
693       WindowOpenDisposition::CURRENT_TAB, blink::WebMouseEvent::Button::kLeft,
694       EXPECT_ORIGIN_AS_REFERRER);
695 }
696
697 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
698                        HttpLeftClickRedirectToHTTPOriginWhenCrossOrigin) {
699   RunReferrerTest(network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin,
700                   START_ON_HTTP, REGULAR_LINK,
701                   SERVER_REDIRECT_FROM_HTTP_TO_HTTP,
702                   WindowOpenDisposition::CURRENT_TAB,
703                   blink::WebMouseEvent::Button::kLeft, EXPECT_FULL_REFERRER);
704 }
705
706 // Same origin
707
708 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
709                        HttpLeftClickHTTPRedirectToHTTPSameOrigin) {
710   RunReferrerTest(network::mojom::ReferrerPolicy::kSameOrigin, START_ON_HTTP,
711                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTP_TO_HTTP,
712                   WindowOpenDisposition::CURRENT_TAB,
713                   blink::WebMouseEvent::Button::kLeft, EXPECT_FULL_REFERRER);
714 }
715
716 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
717                        HttpLeftClickHTTPRedirectToHTTPSSameOrigin) {
718   RunReferrerTest(network::mojom::ReferrerPolicy::kSameOrigin, START_ON_HTTPS,
719                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
720                   WindowOpenDisposition::CURRENT_TAB,
721                   blink::WebMouseEvent::Button::kLeft, EXPECT_EMPTY_REFERRER);
722 }
723
724 // Strict origin
725
726 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
727                        HttpLeftClickHTTPRedirectToHTTPStrictOrigin) {
728   RunReferrerTest(network::mojom::ReferrerPolicy::kStrictOrigin, START_ON_HTTP,
729                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTP_TO_HTTP,
730                   WindowOpenDisposition::CURRENT_TAB,
731                   blink::WebMouseEvent::Button::kLeft,
732                   EXPECT_ORIGIN_AS_REFERRER);
733 }
734
735 IN_PROC_BROWSER_TEST_F(ReferrerPolicyTest,
736                        HttpLeftClickHTTPSRedirectToHTTPStrictOrigin) {
737   RunReferrerTest(network::mojom::ReferrerPolicy::kStrictOrigin, START_ON_HTTPS,
738                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
739                   WindowOpenDisposition::CURRENT_TAB,
740                   blink::WebMouseEvent::Button::kLeft, EXPECT_EMPTY_REFERRER);
741 }
742
743 // Parameters for testing functionality imposing ad-hoc restrictions
744 // on the behavior of referrers, for instance absolute caps like
745 // "never send referrers" (as of writing, features::kNoReferrers)
746 // or "on cross-origin requests, never send more than the initiator's
747 // origin" (features::kCapReferrerToOriginOnCrossOrigin).
748 //
749 // These tests assume a default policy of no-referrer-when-downgrade.
750 struct ReferrerOverrideParams {
751   absl::optional<base::Feature> feature_to_enable;
752   network::mojom::ReferrerPolicy baseline_policy;
753   network::mojom::ReferrerPolicy expected_policy;
754
755   ReferrerPolicyTest::ExpectedReferrer same_origin_nav,  // HTTP -> HTTP
756       cross_origin_nav,                                  // HTTP -> HTTP
757       cross_origin_downgrade_nav,  // HTTPS -> HTTP, cross-origin
758       same_origin_to_cross_origin_redirect,
759       cross_origin_to_same_origin_redirect, same_origin_subresource,
760       same_origin_to_cross_origin_subresource_redirect;
761 } kReferrerOverrideParams[] = {
762     {.feature_to_enable = features::kNoReferrers,
763      .baseline_policy = network::mojom::ReferrerPolicy::kAlways,
764      // The renderer's "have we completely disabled referrers?"
765      // implementation resets requests' referrer policies to kNever when
766      // it excises their referrers.
767      .expected_policy = network::mojom::ReferrerPolicy::kNever,
768      .same_origin_nav = ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
769      .cross_origin_nav = ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
770      .cross_origin_downgrade_nav = ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
771      .same_origin_to_cross_origin_redirect =
772          ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
773      .cross_origin_to_same_origin_redirect =
774          ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
775      .same_origin_subresource = ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
776      .same_origin_to_cross_origin_subresource_redirect =
777          ReferrerPolicyTest::EXPECT_EMPTY_REFERRER},
778     {
779         .feature_to_enable = net::features::kCapReferrerToOriginOnCrossOrigin,
780         .baseline_policy = network::mojom::ReferrerPolicy::kAlways,
781         // Applying the cap doesn't change the "referrer policy"
782         // attribute of a request
783         .expected_policy = network::mojom::ReferrerPolicy::kAlways,
784         .same_origin_nav = ReferrerPolicyTest::EXPECT_FULL_REFERRER,
785         .cross_origin_nav = ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
786         .cross_origin_downgrade_nav =
787             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
788         .same_origin_to_cross_origin_redirect =
789             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
790         // Referrer policies get applied to whatever the current referrer is:
791         // in the case of a cross-origin -> same-origin redirect, we already
792         // will have truncated the referrer to the initiating origin
793         .cross_origin_to_same_origin_redirect =
794             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
795         .same_origin_subresource = ReferrerPolicyTest::EXPECT_FULL_REFERRER,
796         .same_origin_to_cross_origin_subresource_redirect =
797             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
798     },
799     {
800         .baseline_policy = network::mojom::ReferrerPolicy::kDefault,
801         // kDefault gets resolved into a concrete policy when making requests
802         .expected_policy =
803             network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin,
804         .same_origin_nav = ReferrerPolicyTest::EXPECT_FULL_REFERRER,
805         .cross_origin_nav = ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
806         .cross_origin_downgrade_nav = ReferrerPolicyTest::EXPECT_EMPTY_REFERRER,
807         .same_origin_to_cross_origin_redirect =
808             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
809         .cross_origin_to_same_origin_redirect =
810             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
811         .same_origin_subresource = ReferrerPolicyTest::EXPECT_FULL_REFERRER,
812         .same_origin_to_cross_origin_subresource_redirect =
813             ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER,
814     }};
815
816 class ReferrerOverrideTest
817     : public ReferrerPolicyTest,
818       public ::testing::WithParamInterface<ReferrerOverrideParams> {
819  public:
820   ReferrerOverrideTest() {
821     if (GetParam().feature_to_enable)
822       scoped_feature_list_.InitAndEnableFeature(*GetParam().feature_to_enable);
823   }
824
825  protected:
826   // Test that the correct referrer is sent along with
827   // a subresource request.
828   // Parameter semantics are the same as for
829   // ReferrerPolicyTest::RunReferrerTest.
830   void RunSubresourceTest(StartOnProtocol start_protocol,
831                           RedirectType redirect,
832                           network::mojom::ReferrerPolicy baseline_policy,
833                           ExpectedReferrer expectation) {
834     GURL image_url;
835     switch (redirect) {
836       case NO_REDIRECT:
837         image_url = embedded_test_server()->GetURL("/referrer_policy/logo.gif");
838         break;
839       case HTTPS_NO_REDIRECT:
840         image_url = https_server_.GetURL("/referrer_policy/logo.gif");
841         break;
842       case SERVER_REDIRECT_FROM_HTTPS_TO_HTTP:
843         image_url = https_server_.GetURL(
844             std::string("/server-redirect?") +
845             embedded_test_server()->GetURL("/referrer_policy/logo.gif").spec());
846         break;
847       case SERVER_REDIRECT_FROM_HTTP_TO_HTTP:
848         image_url = embedded_test_server()->GetURL(
849             std::string("/server-redirect?") +
850             embedded_test_server()->GetURL("/referrer_policy/logo.gif").spec());
851         break;
852       case SERVER_REDIRECT_FROM_HTTP_TO_HTTPS:
853         image_url = embedded_test_server()->GetURL(
854             std::string("/server-redirect?") +
855             https_server_.GetURL("/referrer_policy/logo.gif").spec());
856         break;
857     }
858
859     std::string relative_url =
860         std::string("/referrer_policy/referrer-policy-subresource.html?") +
861         "policy=" + content::ReferrerPolicyToString(baseline_policy) +
862         "&redirect=" + image_url.spec();
863
864     auto* start_server = start_protocol == START_ON_HTTPS
865                              ? &https_server_
866                              : embedded_test_server();
867     const GURL start_url = start_server->GetURL(relative_url);
868
869     content::WebContents* tab =
870         browser()->tab_strip_model()->GetActiveWebContents();
871
872     base::ReleasableAutoLock lock(&check_on_requests_lock_);
873     check_on_requests_ = RequestCheck{"", "/referrer_policy/logo.gif"};
874     switch (expectation) {
875       case ReferrerPolicyTest::EXPECT_EMPTY_REFERRER:
876         check_on_requests_->expected_spec = "";
877         break;
878       case ReferrerPolicyTest::EXPECT_FULL_REFERRER:
879         check_on_requests_->expected_spec = start_url.spec();
880         break;
881       case ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER:
882         check_on_requests_->expected_spec = start_url.GetWithEmptyPath().spec();
883         break;
884     }
885     lock.Release();
886
887     // set by referrer-policy-subresource.html JS after the embedded image loads
888     std::u16string expected_title(u"loaded");
889     std::unique_ptr<content::TitleWatcher> title_watcher(
890         new content::TitleWatcher(tab, expected_title));
891     ui_test_utils::NavigateToURL(browser(), start_url);
892
893     // Wait for the page to load; during the load, since check_on_requests_ is
894     // nonempty, OnServerIncomingRequest will validate the referrers.
895     EXPECT_EQ(expected_title, title_watcher->WaitAndGetTitle());
896   }
897
898  private:
899   base::test::ScopedFeatureList scoped_feature_list_;
900 };
901
902 INSTANTIATE_TEST_SUITE_P(
903     WithOverrideParams,
904     ReferrerOverrideTest,
905     ::testing::ValuesIn(kReferrerOverrideParams),
906     [](const ::testing::TestParamInfo<ReferrerOverrideParams>& info)
907         -> std::string {
908       if (info.param.feature_to_enable)
909         return base::StringPrintf("Param%s",
910                                   info.param.feature_to_enable->name);
911       return "NoFeature";
912     });
913
914 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, SameOriginNavigation) {
915   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTP, REGULAR_LINK,
916                   NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
917                   blink::WebMouseEvent::Button::kNoButton,
918                   GetParam().same_origin_nav, GetParam().expected_policy);
919 }
920
921 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, CrossOriginNavigation) {
922   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTP, REGULAR_LINK,
923                   HTTPS_NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
924                   blink::WebMouseEvent::Button::kNoButton,
925                   GetParam().cross_origin_nav, GetParam().expected_policy);
926 }
927
928 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest,
929                        CrossOriginNavigationBrowserInitiated) {
930   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTP, REGULAR_LINK,
931                   HTTPS_NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
932                   blink::WebMouseEvent::Button::kLeft,
933                   GetParam().cross_origin_nav, GetParam().expected_policy,
934                   BROWSER_INITIATED);
935 }
936
937 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, CrossOriginDowngradeNavigation) {
938   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTPS, REGULAR_LINK,
939                   NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
940                   blink::WebMouseEvent::Button::kNoButton,
941                   GetParam().cross_origin_downgrade_nav,
942                   GetParam().expected_policy);
943 }
944
945 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, CrossOriginRedirect) {
946   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTP, REGULAR_LINK,
947                   SERVER_REDIRECT_FROM_HTTP_TO_HTTPS,
948                   WindowOpenDisposition::CURRENT_TAB,
949                   blink::WebMouseEvent::Button::kNoButton,
950                   GetParam().same_origin_to_cross_origin_redirect,
951                   GetParam().expected_policy);
952 }
953
954 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, CrossOriginToSameOriginRedirect) {
955   RunReferrerTest(GetParam().baseline_policy, START_ON_HTTP, REGULAR_LINK,
956                   SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
957                   WindowOpenDisposition::CURRENT_TAB,
958                   blink::WebMouseEvent::Button::kNoButton,
959                   GetParam().cross_origin_to_same_origin_redirect,
960                   GetParam().expected_policy);
961 }
962
963 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest, SameOriginSubresource) {
964   RunSubresourceTest(START_ON_HTTP, NO_REDIRECT, GetParam().baseline_policy,
965                      GetParam().same_origin_subresource);
966 }
967
968 IN_PROC_BROWSER_TEST_P(ReferrerOverrideTest,
969                        SameOriginToCrossOriginSubresourceRedirect) {
970   RunSubresourceTest(
971       START_ON_HTTP, SERVER_REDIRECT_FROM_HTTP_TO_HTTPS,
972       GetParam().baseline_policy,
973       GetParam().same_origin_to_cross_origin_subresource_redirect);
974 }
975
976 // Most of the functionality of the referrer-cap flag is covered by
977 // ReferrerOverrideTest; these couple additional tests test the flag's
978 // interaction with other referrer policies
979 class ReferrerPolicyCapReferrerToOriginOnCrossOriginTest
980     : public ReferrerPolicyTest {
981  public:
982   ReferrerPolicyCapReferrerToOriginOnCrossOriginTest() {
983     scoped_feature_list_.InitAndEnableFeature(
984         net::features::kCapReferrerToOriginOnCrossOrigin);
985   }
986
987  private:
988   base::test::ScopedFeatureList scoped_feature_list_;
989 };
990
991 // Test that capping referrer granularity at origin on cross-origin requests
992 // correctly defers to a more restrictive referrer policy on a
993 // cross-origin navigation.
994 IN_PROC_BROWSER_TEST_F(ReferrerPolicyCapReferrerToOriginOnCrossOriginTest,
995                        HonorsMoreRestrictivePolicyOnNavigation) {
996   RunReferrerTest(network::mojom::ReferrerPolicy::kSameOrigin, START_ON_HTTPS,
997                   REGULAR_LINK, NO_REDIRECT /*direct navigation x-origin*/,
998                   WindowOpenDisposition::CURRENT_TAB,
999                   blink::WebMouseEvent::Button::kLeft, EXPECT_EMPTY_REFERRER);
1000 }
1001
1002 // Test that capping referrer granularity at origin on cross-origin requests
1003 // correctly defers to a more restrictive referrer policy on a
1004 // cross-origin redirect.
1005 IN_PROC_BROWSER_TEST_F(ReferrerPolicyCapReferrerToOriginOnCrossOriginTest,
1006                        HonorsMoreRestrictivePolicyOnRedirect) {
1007   RunReferrerTest(network::mojom::ReferrerPolicy::kStrictOrigin, START_ON_HTTPS,
1008                   REGULAR_LINK, SERVER_REDIRECT_FROM_HTTPS_TO_HTTP,
1009                   WindowOpenDisposition::CURRENT_TAB,
1010                   blink::WebMouseEvent::Button::kLeft, EXPECT_EMPTY_REFERRER);
1011 }
1012
1013 // Test that, when the cross-origin referrer cap is on but we also have the
1014 // "no referrers at all" pref set, we send no referrer at all on cross-origin
1015 // requests.
1016 IN_PROC_BROWSER_TEST_F(ReferrerPolicyCapReferrerToOriginOnCrossOriginTest,
1017                        RespectsNoReferrerPref) {
1018   browser()->profile()->GetPrefs()->SetBoolean(prefs::kEnableReferrers, false);
1019   browser()
1020       ->profile()
1021       ->GetDefaultStoragePartition()
1022       ->FlushNetworkInterfaceForTesting();
1023   RunReferrerTest(network::mojom::ReferrerPolicy::kAlways, START_ON_HTTPS,
1024                   REGULAR_LINK, NO_REDIRECT, WindowOpenDisposition::CURRENT_TAB,
1025                   blink::WebMouseEvent::Button::kLeft, EXPECT_EMPTY_REFERRER,
1026                   // when the pref is set, the renderer sets the referrer policy
1027                   // to the kNever on outgoing requests at the same time
1028                   // it removes referrers
1029                   network::mojom::ReferrerPolicy::kNever);
1030 }