| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/message_loop.h" | 5 #include "base/message_loop.h" |
| 6 #include "chrome/browser/extensions/api/identity/web_auth_flow.h" | 6 #include "chrome/browser/extensions/api/identity/experimental_web_auth_flow.h" |
| 7 #include "chrome/browser/ui/host_desktop.h" | 7 #include "chrome/browser/ui/host_desktop.h" |
| 8 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 8 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
| 9 #include "chrome/test/base/testing_profile.h" | 9 #include "chrome/test/base/testing_profile.h" |
| 10 #include "content/public/browser/browser_thread.h" | 10 #include "content/public/browser/browser_thread.h" |
| 11 #include "content/public/browser/web_contents.h" | 11 #include "content/public/browser/web_contents.h" |
| 12 #include "content/public/test/test_browser_thread.h" | 12 #include "content/public/test/test_browser_thread.h" |
| 13 #include "content/public/test/web_contents_tester.h" | 13 #include "content/public/test/web_contents_tester.h" |
| 14 #include "testing/gmock/include/gmock/gmock.h" | 14 #include "testing/gmock/include/gmock/gmock.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 16 | 16 |
| 17 using content::BrowserThread; | 17 using content::BrowserThread; |
| 18 using content::TestBrowserThread; | 18 using content::TestBrowserThread; |
| 19 using content::WebContents; | 19 using content::WebContents; |
| 20 using content::WebContentsTester; | 20 using content::WebContentsTester; |
| 21 using extensions::WebAuthFlow; | 21 using extensions::ExperimentalWebAuthFlow; |
| 22 using testing::Return; | 22 using testing::Return; |
| 23 using testing::ReturnRef; | 23 using testing::ReturnRef; |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 class MockDelegate : public WebAuthFlow::Delegate { | 27 class MockDelegate : public ExperimentalWebAuthFlow::Delegate { |
| 28 public: | 28 public: |
| 29 MOCK_METHOD1(OnAuthFlowFailure, void(WebAuthFlow::Failure failure)); | 29 MOCK_METHOD1(OnAuthFlowFailure, |
| 30 void(ExperimentalWebAuthFlow::Failure failure)); |
| 30 MOCK_METHOD1(OnAuthFlowURLChange, void(const GURL& redirect_url)); | 31 MOCK_METHOD1(OnAuthFlowURLChange, void(const GURL& redirect_url)); |
| 31 }; | 32 }; |
| 32 | 33 |
| 33 class MockWebAuthFlow : public WebAuthFlow { | 34 class MockExperimentalWebAuthFlow : public ExperimentalWebAuthFlow { |
| 34 public: | 35 public: |
| 35 MockWebAuthFlow( | 36 MockExperimentalWebAuthFlow(ExperimentalWebAuthFlow::Delegate* delegate, |
| 36 WebAuthFlow::Delegate* delegate, | 37 Profile* profile, |
| 37 Profile* profile, | 38 const GURL& provider_url, |
| 38 const GURL& provider_url, | 39 bool interactive) |
| 39 bool interactive) | 40 : ExperimentalWebAuthFlow( |
| 40 : WebAuthFlow( | 41 delegate, |
| 41 delegate, | 42 profile, |
| 42 profile, | 43 provider_url, |
| 43 provider_url, | 44 interactive ? ExperimentalWebAuthFlow::INTERACTIVE |
| 44 interactive ? WebAuthFlow::INTERACTIVE : WebAuthFlow::SILENT, | 45 : ExperimentalWebAuthFlow::SILENT, |
| 45 gfx::Rect(), | 46 gfx::Rect(), |
| 46 chrome::GetActiveDesktop()), | 47 chrome::GetActiveDesktop()), |
| 47 profile_(profile), | 48 profile_(profile), |
| 48 web_contents_(NULL), | 49 web_contents_(NULL), |
| 49 window_shown_(false) { } | 50 window_shown_(false) {} |
| 50 | 51 |
| 51 virtual WebContents* CreateWebContents() OVERRIDE { | 52 virtual WebContents* CreateWebContents() OVERRIDE { |
| 52 CHECK(!web_contents_); | 53 CHECK(!web_contents_); |
| 53 web_contents_ = WebContentsTester::CreateTestWebContents(profile_, NULL); | 54 web_contents_ = WebContentsTester::CreateTestWebContents(profile_, NULL); |
| 54 return web_contents_; | 55 return web_contents_; |
| 55 } | 56 } |
| 56 | 57 |
| 57 virtual void ShowAuthFlowPopup() OVERRIDE { | 58 virtual void ShowAuthFlowPopup() OVERRIDE { |
| 58 window_shown_ = true; | 59 window_shown_ = true; |
| 59 } | 60 } |
| 60 | 61 |
| 61 bool HasWindow() const { | 62 bool HasWindow() const { |
| 62 return window_shown_; | 63 return window_shown_; |
| 63 } | 64 } |
| 64 | 65 |
| 65 void DestroyWebContents() { | 66 void DestroyWebContents() { |
| 66 CHECK(web_contents_); | 67 CHECK(web_contents_); |
| 67 delete web_contents_; | 68 delete web_contents_; |
| 68 } | 69 } |
| 69 | 70 |
| 70 virtual ~MockWebAuthFlow() { } | 71 virtual ~MockExperimentalWebAuthFlow() { } |
| 71 | 72 |
| 72 private: | 73 private: |
| 73 Profile* profile_; | 74 Profile* profile_; |
| 74 WebContents* web_contents_; | 75 WebContents* web_contents_; |
| 75 bool window_shown_; | 76 bool window_shown_; |
| 76 }; | 77 }; |
| 77 | 78 |
| 78 } // namespace | 79 } // namespace |
| 79 | 80 |
| 80 class WebAuthFlowTest : public ChromeRenderViewHostTestHarness { | 81 class ExperimentalWebAuthFlowTest : public ChromeRenderViewHostTestHarness { |
| 81 protected: | 82 protected: |
| 82 WebAuthFlowTest() | 83 ExperimentalWebAuthFlowTest() |
| 83 : thread_(BrowserThread::UI, &message_loop_) { | 84 : thread_(BrowserThread::UI, &message_loop_) { |
| 84 } | 85 } |
| 85 | 86 |
| 86 virtual void SetUp() { | 87 virtual void SetUp() { |
| 87 ChromeRenderViewHostTestHarness::SetUp(); | 88 ChromeRenderViewHostTestHarness::SetUp(); |
| 88 } | 89 } |
| 89 | 90 |
| 90 virtual void TearDown() { | 91 virtual void TearDown() { |
| 91 // |flow_| must be reset before ChromeRenderViewHostTestHarness::TearDown(), | 92 // |flow_| must be reset before ChromeRenderViewHostTestHarness::TearDown(), |
| 92 // because |flow_| deletes the WebContents it owns via | 93 // because |flow_| deletes the WebContents it owns via |
| 93 // MessageLoop::DeleteSoon(). | 94 // MessageLoop::DeleteSoon(). |
| 94 flow_.reset(); | 95 flow_.reset(); |
| 95 ChromeRenderViewHostTestHarness::TearDown(); | 96 ChromeRenderViewHostTestHarness::TearDown(); |
| 96 } | 97 } |
| 97 | 98 |
| 98 void CreateAuthFlow(const GURL& url, | 99 void CreateAuthFlow(const GURL& url, |
| 99 bool interactive) { | 100 bool interactive) { |
| 100 flow_.reset(new MockWebAuthFlow( | 101 flow_.reset(new MockExperimentalWebAuthFlow( |
| 101 &delegate_, profile(), url, interactive)); | 102 &delegate_, profile(), url, interactive)); |
| 102 } | 103 } |
| 103 | 104 |
| 104 WebAuthFlow* flow_base() { | 105 ExperimentalWebAuthFlow* flow_base() { |
| 105 return flow_.get(); | 106 return flow_.get(); |
| 106 } | 107 } |
| 107 | 108 |
| 108 void CallBeforeUrlLoaded(const GURL& url) { | 109 void CallBeforeUrlLoaded(const GURL& url) { |
| 109 flow_base()->BeforeUrlLoaded(url); | 110 flow_base()->BeforeUrlLoaded(url); |
| 110 } | 111 } |
| 111 | 112 |
| 112 void CallAfterUrlLoaded() { | 113 void CallAfterUrlLoaded() { |
| 113 flow_base()->AfterUrlLoaded(); | 114 flow_base()->AfterUrlLoaded(); |
| 114 } | 115 } |
| 115 | 116 |
| 116 TestBrowserThread thread_; | 117 TestBrowserThread thread_; |
| 117 MockDelegate delegate_; | 118 MockDelegate delegate_; |
| 118 scoped_ptr<MockWebAuthFlow> flow_; | 119 scoped_ptr<MockExperimentalWebAuthFlow> flow_; |
| 119 }; | 120 }; |
| 120 | 121 |
| 121 TEST_F(WebAuthFlowTest, SilentRedirectToChromiumAppUrlNonInteractive) { | 122 TEST_F(ExperimentalWebAuthFlowTest, |
| 123 SilentRedirectToChromiumAppUrlNonInteractive) { |
| 122 GURL url("https://accounts.google.com/o/oauth2/auth"); | 124 GURL url("https://accounts.google.com/o/oauth2/auth"); |
| 123 GURL result("https://abcdefghij.chromiumapp.org/google_cb"); | 125 GURL result("https://abcdefghij.chromiumapp.org/google_cb"); |
| 124 | 126 |
| 125 CreateAuthFlow(url, false); | 127 CreateAuthFlow(url, false); |
| 126 EXPECT_CALL(delegate_, OnAuthFlowURLChange(result)).Times(1); | 128 EXPECT_CALL(delegate_, OnAuthFlowURLChange(result)).Times(1); |
| 127 flow_->Start(); | 129 flow_->Start(); |
| 128 CallBeforeUrlLoaded(result); | 130 CallBeforeUrlLoaded(result); |
| 129 } | 131 } |
| 130 | 132 |
| 131 TEST_F(WebAuthFlowTest, SilentRedirectToChromiumAppUrlInteractive) { | 133 TEST_F(ExperimentalWebAuthFlowTest, SilentRedirectToChromiumAppUrlInteractive) { |
| 132 GURL url("https://accounts.google.com/o/oauth2/auth"); | 134 GURL url("https://accounts.google.com/o/oauth2/auth"); |
| 133 GURL result("https://abcdefghij.chromiumapp.org/google_cb"); | 135 GURL result("https://abcdefghij.chromiumapp.org/google_cb"); |
| 134 | 136 |
| 135 CreateAuthFlow(url, true); | 137 CreateAuthFlow(url, true); |
| 136 EXPECT_CALL(delegate_, OnAuthFlowURLChange(result)).Times(1); | 138 EXPECT_CALL(delegate_, OnAuthFlowURLChange(result)).Times(1); |
| 137 flow_->Start(); | 139 flow_->Start(); |
| 138 CallBeforeUrlLoaded(result); | 140 CallBeforeUrlLoaded(result); |
| 139 } | 141 } |
| 140 | 142 |
| 141 TEST_F(WebAuthFlowTest, SilentRedirectToChromeExtensionSchemeUrl) { | 143 TEST_F(ExperimentalWebAuthFlowTest, SilentRedirectToChromeExtensionSchemeUrl) { |
| 142 GURL url("https://accounts.google.com/o/oauth2/auth"); | 144 GURL url("https://accounts.google.com/o/oauth2/auth"); |
| 143 GURL result("chrome-extension://abcdefghij/google_cb"); | 145 GURL result("chrome-extension://abcdefghij/google_cb"); |
| 144 | 146 |
| 145 CreateAuthFlow(url, true); | 147 CreateAuthFlow(url, true); |
| 146 EXPECT_CALL(delegate_, OnAuthFlowURLChange(result)).Times(1); | 148 EXPECT_CALL(delegate_, OnAuthFlowURLChange(result)).Times(1); |
| 147 flow_->Start(); | 149 flow_->Start(); |
| 148 CallBeforeUrlLoaded(result); | 150 CallBeforeUrlLoaded(result); |
| 149 } | 151 } |
| 150 | 152 |
| 151 TEST_F(WebAuthFlowTest, NeedsUIButNonInteractive) { | 153 TEST_F(ExperimentalWebAuthFlowTest, NeedsUIButNonInteractive) { |
| 152 GURL url("https://accounts.google.com/o/oauth2/auth"); | 154 GURL url("https://accounts.google.com/o/oauth2/auth"); |
| 153 | 155 |
| 154 CreateAuthFlow(url, false); | 156 CreateAuthFlow(url, false); |
| 155 EXPECT_CALL( | 157 EXPECT_CALL(delegate_, |
| 156 delegate_, OnAuthFlowFailure(WebAuthFlow::INTERACTION_REQUIRED)).Times(1); | 158 OnAuthFlowFailure(ExperimentalWebAuthFlow::INTERACTION_REQUIRED)) |
| 159 .Times(1); |
| 157 flow_->Start(); | 160 flow_->Start(); |
| 158 CallAfterUrlLoaded(); | 161 CallAfterUrlLoaded(); |
| 159 } | 162 } |
| 160 | 163 |
| 161 TEST_F(WebAuthFlowTest, UIResultsInSuccess) { | 164 TEST_F(ExperimentalWebAuthFlowTest, UIResultsInSuccess) { |
| 162 GURL url("https://accounts.google.com/o/oauth2/auth"); | 165 GURL url("https://accounts.google.com/o/oauth2/auth"); |
| 163 GURL result("chrome-extension://abcdefghij/google_cb"); | 166 GURL result("chrome-extension://abcdefghij/google_cb"); |
| 164 | 167 |
| 165 CreateAuthFlow(url, true); | 168 CreateAuthFlow(url, true); |
| 166 EXPECT_CALL(delegate_, OnAuthFlowURLChange(result)).Times(1); | 169 EXPECT_CALL(delegate_, OnAuthFlowURLChange(result)).Times(1); |
| 167 flow_->Start(); | 170 flow_->Start(); |
| 168 CallAfterUrlLoaded(); | 171 CallAfterUrlLoaded(); |
| 169 EXPECT_TRUE(flow_->HasWindow()); | 172 EXPECT_TRUE(flow_->HasWindow()); |
| 170 CallBeforeUrlLoaded(result); | 173 CallBeforeUrlLoaded(result); |
| 171 } | 174 } |
| 172 | 175 |
| 173 TEST_F(WebAuthFlowTest, UIClosedByUser) { | 176 TEST_F(ExperimentalWebAuthFlowTest, UIClosedByUser) { |
| 174 GURL url("https://accounts.google.com/o/oauth2/auth"); | 177 GURL url("https://accounts.google.com/o/oauth2/auth"); |
| 175 GURL result("chrome-extension://abcdefghij/google_cb"); | 178 GURL result("chrome-extension://abcdefghij/google_cb"); |
| 176 | 179 |
| 177 CreateAuthFlow(url, true); | 180 CreateAuthFlow(url, true); |
| 178 EXPECT_CALL( | 181 EXPECT_CALL(delegate_, |
| 179 delegate_, OnAuthFlowFailure(WebAuthFlow::WINDOW_CLOSED)).Times(1); | 182 OnAuthFlowFailure(ExperimentalWebAuthFlow::WINDOW_CLOSED)) |
| 183 .Times(1); |
| 180 flow_->Start(); | 184 flow_->Start(); |
| 181 CallAfterUrlLoaded(); | 185 CallAfterUrlLoaded(); |
| 182 EXPECT_TRUE(flow_->HasWindow()); | 186 EXPECT_TRUE(flow_->HasWindow()); |
| 183 flow_->DestroyWebContents(); | 187 flow_->DestroyWebContents(); |
| 184 } | 188 } |
| OLD | NEW |