| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/local_discovery/privetv3_setup_flow.h" |
| |
| #include "base/json/json_reader.h" |
| #include "base/run_loop.h" |
| #include "chrome/browser/local_discovery/gcd_api_flow.h" |
| #include "net/http/http_response_headers.h" |
| #include "net/url_request/test_url_fetcher_factory.h" |
| #include "net/url_request/url_request_test_util.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace local_discovery { |
| |
| namespace { |
| |
| using testing::HasSubstr; |
| using testing::Invoke; |
| using testing::Return; |
| using testing::SaveArg; |
| using testing::StrictMock; |
| using testing::WithArgs; |
| using testing::_; |
| |
| const char kServiceName[] = "test_service"; |
| |
| const char kRegistrationTicketResponse[] = |
| "{" |
| "\"kind\": \"clouddevices#registrationTicket\"," |
| "\"id\": \"test_ticket\"," |
| "\"deviceId\": \"test_id\"" |
| "}"; |
| |
| class MockPrivetHTTPClient : public PrivetHTTPClient { |
| public: |
| MockPrivetHTTPClient() { |
| request_context_ = |
| new net::TestURLRequestContextGetter(base::MessageLoopProxy::current()); |
| } |
| |
| MOCK_METHOD0(GetName, const std::string&()); |
| MOCK_METHOD1( |
| CreateInfoOperationPtr, |
| PrivetJSONOperation*(const PrivetJSONOperation::ResultCallback&)); |
| |
| virtual void RefreshPrivetToken( |
| const PrivetURLFetcher::TokenCallback& callback) OVERRIDE { |
| callback.Run("x-privet-token"); |
| } |
| |
| virtual scoped_ptr<PrivetJSONOperation> CreateInfoOperation( |
| const PrivetJSONOperation::ResultCallback& callback) OVERRIDE { |
| return make_scoped_ptr(CreateInfoOperationPtr(callback)); |
| } |
| |
| virtual scoped_ptr<PrivetURLFetcher> CreateURLFetcher( |
| const GURL& url, |
| net::URLFetcher::RequestType request_type, |
| PrivetURLFetcher::Delegate* delegate) OVERRIDE { |
| return make_scoped_ptr( |
| new PrivetURLFetcher(url, request_type, request_context_, delegate)); |
| } |
| |
| scoped_refptr<net::TestURLRequestContextGetter> request_context_; |
| }; |
| |
| class MockDelegate : public PrivetV3SetupFlow::Delegate { |
| public: |
| MockDelegate() : privet_client_ptr_(NULL) {} |
| |
| class MockGCDApiFlow : public GCDApiFlow { |
| public: |
| explicit MockGCDApiFlow(MockDelegate* delegate) : delegate_(delegate) {} |
| |
| virtual void Start(scoped_ptr<Request> request) OVERRIDE { |
| ASSERT_FALSE(delegate_->gcd_request_); |
| delegate_->gcd_request_ = request.Pass(); |
| delegate_->ReplyWithToken(); |
| } |
| |
| private: |
| MockDelegate* delegate_; |
| }; |
| |
| MOCK_METHOD1(GetWiFiCredentials, void(const CredentialsCallback&)); |
| MOCK_METHOD1(SwitchToSetupWiFi, void(const ResultCallback&)); |
| virtual void CreatePrivetV3Client( |
| const std::string& service_name, |
| const PrivetClientCallback& callback) OVERRIDE { |
| scoped_ptr<MockPrivetHTTPClient> privet_client(new MockPrivetHTTPClient()); |
| privet_client_ptr_ = privet_client.get(); |
| callback.Run(privet_client.PassAs<PrivetHTTPClient>()); |
| } |
| MOCK_METHOD2(ConfirmSecurityCode, |
| void(const std::string&, const ResultCallback&)); |
| MOCK_METHOD1(RestoreWifi, void(const ResultCallback&)); |
| MOCK_METHOD0(OnSetupDone, void()); |
| MOCK_METHOD0(OnSetupError, void()); |
| |
| virtual scoped_ptr<GCDApiFlow> CreateApiFlow() OVERRIDE { |
| scoped_ptr<MockGCDApiFlow> mock_gcd(new MockGCDApiFlow(this)); |
| return mock_gcd.PassAs<GCDApiFlow>(); |
| } |
| |
| void ReplyWithToken() { |
| scoped_ptr<base::Value> value(base::JSONReader::Read(gcd_server_response_)); |
| const base::DictionaryValue* dictionary = NULL; |
| value->GetAsDictionary(&dictionary); |
| gcd_request_->OnGCDAPIFlowComplete(*dictionary); |
| } |
| |
| std::string gcd_server_response_; |
| scoped_ptr<GCDApiFlow::Request> gcd_request_; |
| MockPrivetHTTPClient* privet_client_ptr_; |
| base::Closure quit_closure_; |
| }; |
| |
| class PrivetV3SetupFlowTest : public testing::Test { |
| public: |
| PrivetV3SetupFlowTest() : setup_(&delegate_) {} |
| |
| virtual ~PrivetV3SetupFlowTest() {} |
| |
| void ConfirmCode(const MockDelegate::ResultCallback& confirm_callback) { |
| base::MessageLoop::current()->PostTask(FROM_HERE, quit_closure_); |
| confirm_callback.Run(true); |
| } |
| |
| protected: |
| virtual void SetUp() OVERRIDE { |
| quit_closure_ = run_loop_.QuitClosure(); |
| EXPECT_CALL(delegate_, GetWiFiCredentials(_)).Times(0); |
| EXPECT_CALL(delegate_, SwitchToSetupWiFi(_)).Times(0); |
| EXPECT_CALL(delegate_, ConfirmSecurityCode(_, _)).Times(0); |
| EXPECT_CALL(delegate_, RestoreWifi(_)).Times(0); |
| EXPECT_CALL(delegate_, OnSetupDone()).Times(0); |
| EXPECT_CALL(delegate_, OnSetupError()).Times(0); |
| } |
| |
| void SimulateFetch(int response_code, const std::string& response) { |
| net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); |
| ASSERT_TRUE(fetcher); |
| EXPECT_THAT(fetcher->GetOriginalURL().spec(), |
| testing::HasSubstr("/privet/v3/setup/start")); |
| fetcher->set_response_code(response_code); |
| scoped_refptr<net::HttpResponseHeaders> response_headers( |
| new net::HttpResponseHeaders("")); |
| response_headers->AddHeader("Content-Type: application/json"); |
| fetcher->set_response_headers(response_headers); |
| fetcher->SetResponseString(response); |
| fetcher->delegate()->OnURLFetchComplete(fetcher); |
| } |
| |
| net::TestURLFetcherFactory url_fetcher_factory_; |
| StrictMock<MockDelegate> delegate_; |
| PrivetV3SetupFlow setup_; |
| base::MessageLoop loop_; |
| base::RunLoop run_loop_; |
| base::Closure quit_closure_; |
| }; |
| |
| TEST_F(PrivetV3SetupFlowTest, InvalidTicket) { |
| EXPECT_CALL(delegate_, OnSetupError()).Times(1); |
| delegate_.gcd_server_response_ = "{}"; |
| setup_.Register(kServiceName); |
| } |
| |
| TEST_F(PrivetV3SetupFlowTest, InvalidDeviceResponce) { |
| EXPECT_CALL(delegate_, OnSetupError()).Times(1); |
| EXPECT_CALL(delegate_, ConfirmSecurityCode(_, _)).Times(1).WillOnce( |
| WithArgs<1>(Invoke(this, &PrivetV3SetupFlowTest::ConfirmCode))); |
| delegate_.gcd_server_response_ = kRegistrationTicketResponse; |
| setup_.Register(kServiceName); |
| run_loop_.Run(); |
| SimulateFetch(0, "{}"); |
| } |
| |
| TEST_F(PrivetV3SetupFlowTest, Success) { |
| EXPECT_CALL(delegate_, OnSetupDone()).Times(1); |
| EXPECT_CALL(delegate_, ConfirmSecurityCode(_, _)).Times(1).WillOnce( |
| WithArgs<1>(Invoke(this, &PrivetV3SetupFlowTest::ConfirmCode))); |
| delegate_.gcd_server_response_ = kRegistrationTicketResponse; |
| setup_.Register(kServiceName); |
| run_loop_.Run(); |
| SimulateFetch(200, "{}"); |
| } |
| |
| } // namespace |
| |
| } // namespace local_discovery |