// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Isolate login client unit tests.
//

#include <string>

#include <base/files/file_path.h>
#include <chromeos/secure_blob.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "chaps/isolate_login_client.h"
#include "chaps/isolate_mock.h"
#include "chaps/token_file_manager_mock.h"
#include "chaps/token_manager_client_mock.h"

using base::FilePath;
using chromeos::SecureBlob;
using std::string;
using std::vector;
using ::testing::_;
using ::testing::DoAll;
using ::testing::Eq;
using ::testing::Return;
using ::testing::SetArgumentPointee;

namespace chaps {

class TestIsolateLoginClient : public ::testing::Test {
 protected:
  virtual void SetUp() {
    user_ = string("user");
    auth_old_ = SecureBlob("auth_old");
    auth_new_ = SecureBlob("auth_new");
    salted_auth_old_ = SecureBlob("salted_auth_old");
    salted_auth_new_ = SecureBlob("salted_auth_new");
    isolate_credential_ = SecureBlob("credential");
    token_path_ = FilePath("token_path");
    isolate_login_client_.reset(new IsolateLoginClient(&isolate_manager_mock_,
                                                       &file_manager_mock_,
                                                       &token_manager_mock_));

    EXPECT_CALL(isolate_manager_mock_, GetUserIsolateCredential(user_, _))
        .WillRepeatedly(DoAll(SetArgumentPointee<1>(isolate_credential_),
                              Return(true)));
    EXPECT_CALL(token_manager_mock_, OpenIsolate(_, _))
         .WillRepeatedly(DoAll(SetArgumentPointee<1>(false), Return(true)));
    EXPECT_CALL(file_manager_mock_, GetUserTokenPath(user_, _))
         .WillRepeatedly(DoAll(SetArgumentPointee<1>(token_path_),
                               Return(true)));
    EXPECT_CALL(file_manager_mock_, CheckUserTokenPermissions(token_path_))
         .WillRepeatedly(Return(true));
    EXPECT_CALL(file_manager_mock_, SaltAuthData(token_path_, auth_old_, _))
         .WillRepeatedly(DoAll(SetArgumentPointee<2>(salted_auth_old_),
                               Return(true)));
    EXPECT_CALL(file_manager_mock_, SaltAuthData(token_path_, auth_new_, _))
         .WillRepeatedly(DoAll(SetArgumentPointee<2>(salted_auth_new_),
                               Return(true)));
  }
  string user_;
  SecureBlob auth_old_;
  SecureBlob auth_new_;
  SecureBlob salted_auth_old_;
  SecureBlob salted_auth_new_;
  SecureBlob isolate_credential_;
  FilePath token_path_;
  IsolateCredentialManagerMock isolate_manager_mock_;
  TokenFileManagerMock file_manager_mock_;
  TokenManagerClientMock token_manager_mock_;
  scoped_ptr<IsolateLoginClient> isolate_login_client_;
};

TEST_F(TestIsolateLoginClient, TestLoginUserSuccess) {
  EXPECT_CALL(token_manager_mock_, LoadToken(isolate_credential_,
                                             token_path_,
                                             salted_auth_new_,
                                             user_,
                                             _))
      .WillOnce(Return(true));

  EXPECT_TRUE(isolate_login_client_->LoginUser(user_, auth_new_));
}

TEST_F(TestIsolateLoginClient, TestLoginUserFail) {
  EXPECT_CALL(token_manager_mock_, OpenIsolate(_, _))
      .WillOnce(DoAll(SetArgumentPointee<1>(false), Return(false)))
      .WillRepeatedly(DoAll(SetArgumentPointee<1>(false), Return(true)));
  EXPECT_CALL(token_manager_mock_, LoadToken(isolate_credential_,
                                            token_path_,
                                            salted_auth_new_,
                                            user_,
                                            _))
      .WillOnce(Return(false));

  EXPECT_FALSE(isolate_login_client_->LoginUser(user_, auth_new_));
  EXPECT_FALSE(isolate_login_client_->LoginUser(user_, auth_new_));
}

TEST_F(TestIsolateLoginClient, TestLoginUserNewIsolate) {
  EXPECT_CALL(isolate_manager_mock_, GetUserIsolateCredential(user_, _))
      .WillOnce(DoAll(SetArgumentPointee<1>(SecureBlob("invalid")),
                      Return(true)));
  EXPECT_CALL(token_manager_mock_, OpenIsolate(_, _))
      .WillOnce(DoAll(SetArgumentPointee<0>(isolate_credential_),
                      SetArgumentPointee<1>(true),
                      Return(true)));
  EXPECT_CALL(isolate_manager_mock_,
              SaveIsolateCredential(user_, isolate_credential_))
      .WillOnce(Return(true));
  EXPECT_CALL(token_manager_mock_, LoadToken(isolate_credential_,
                                             token_path_,
                                             salted_auth_new_,
                                             user_,
                                             _))
      .WillOnce(Return(true));

  EXPECT_TRUE(isolate_login_client_->LoginUser(user_, auth_new_));
}

TEST_F(TestIsolateLoginClient, TestLoginUserCreateToken) {
  EXPECT_CALL(file_manager_mock_, GetUserTokenPath(user_, _))
       .WillOnce(DoAll(SetArgumentPointee<1>(token_path_), Return(false)));
  EXPECT_CALL(file_manager_mock_, CreateUserTokenDirectory(token_path_))
       .WillOnce(Return(true));
  EXPECT_CALL(token_manager_mock_, LoadToken(isolate_credential_,
                                             token_path_,
                                             salted_auth_new_,
                                             user_,
                                             _))
      .WillOnce(Return(true));

  EXPECT_TRUE(isolate_login_client_->LoginUser(user_, auth_new_));
}

TEST_F(TestIsolateLoginClient, TestLoginUserBadTokenPerms) {
  EXPECT_CALL(file_manager_mock_, CheckUserTokenPermissions(token_path_))
       .WillOnce(Return(false));

  EXPECT_FALSE(isolate_login_client_->LoginUser(user_, auth_new_));
}

TEST_F(TestIsolateLoginClient, TestLogoutSuccess) {
  EXPECT_CALL(token_manager_mock_, CloseIsolate(isolate_credential_));

  EXPECT_TRUE(isolate_login_client_->LogoutUser(user_));
}

TEST_F(TestIsolateLoginClient, TestLogoutInvalid) {
  EXPECT_CALL(isolate_manager_mock_, GetUserIsolateCredential(user_, _))
      .WillOnce(Return(false));

  EXPECT_FALSE(isolate_login_client_->LogoutUser(user_));
}

TEST_F(TestIsolateLoginClient, TestChangeUsersAuthSuccess) {
  EXPECT_CALL(token_manager_mock_, ChangeTokenAuthData(token_path_,
                                                       salted_auth_old_,
                                                       salted_auth_new_));

  EXPECT_TRUE(isolate_login_client_->ChangeUserAuth(user_, auth_old_,
                                                    auth_new_));
}

TEST_F(TestIsolateLoginClient, TestChangeUsersAuthNoToken) {
  EXPECT_CALL(file_manager_mock_, GetUserTokenPath(user_, _))
       .WillOnce(DoAll(SetArgumentPointee<1>(token_path_), Return(false)));

  EXPECT_FALSE(isolate_login_client_->ChangeUserAuth(user_, auth_old_,
                                                     auth_new_));
}

TEST_F(TestIsolateLoginClient, TestChangeUsersAuthBadTokenPerms) {
  EXPECT_CALL(file_manager_mock_, CheckUserTokenPermissions(token_path_))
       .WillOnce(Return(false));

  EXPECT_FALSE(isolate_login_client_->ChangeUserAuth(user_, auth_old_,
                                                     auth_new_));
}

}  // namespace chaps

int main(int argc, char** argv) {
  ::testing::InitGoogleMock(&argc, argv);
  return RUN_ALL_TESTS();
}
