// Copyright (c) 2017 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 "components/password_manager/core/browser/password_reuse_detection_manager.h"

#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/simple_test_clock.h"
#include "components/password_manager/core/browser/mock_password_store.h"
#include "components/password_manager/core/browser/stub_password_manager_client.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/keycodes/keyboard_codes_posix.h"
#include "url/gurl.h"

using base::ASCIIToUTF16;
using testing::AnyNumber;
using testing::_;

namespace password_manager {

namespace {

constexpr size_t kMaxNumberOfCharactersToStore = 30;

class MockPasswordManagerClient : public StubPasswordManagerClient {
 public:
  MockPasswordManagerClient() = default;
  ~MockPasswordManagerClient() override = default;

  MOCK_CONST_METHOD0(GetPasswordStore, PasswordStore*());

 private:
  DISALLOW_COPY_AND_ASSIGN(MockPasswordManagerClient);
};

class PasswordReuseDetectionManagerTest : public ::testing::Test {
 public:
  PasswordReuseDetectionManagerTest() {}
  void SetUp() override {
    store_ = new testing::StrictMock<MockPasswordStore>;
    CHECK(store_->Init(syncer::SyncableService::StartSyncFlare(), nullptr));
  }
  void TearDown() override {
    store_->ShutdownOnUIThread();
    store_ = nullptr;
  }

 protected:
  // It's needed for an initialisation of thread runners that are used in
  // MockPasswordStore.
  base::test::ScopedTaskEnvironment scoped_task_environment_;
  MockPasswordManagerClient client_;
  scoped_refptr<MockPasswordStore> store_;

  DISALLOW_COPY_AND_ASSIGN(PasswordReuseDetectionManagerTest);
};

// Verify that CheckReuse is called on each key pressed event with an argument
// equal to the last 30 keystrokes typed after the last main frame navigation.
TEST_F(PasswordReuseDetectionManagerTest, CheckReuseCalled) {
  const GURL gurls[] = {GURL("https://www.example.com"),
                        GURL("https://www.otherexample.com")};
  const base::string16 input[] = {
      base::ASCIIToUTF16(
          "1234567890abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVXYZ"),
      base::ASCIIToUTF16("?<>:'{}ABCDEF")};

  EXPECT_CALL(client_, GetPasswordStore())
      .WillRepeatedly(testing::Return(store_.get()));
  PasswordReuseDetectionManager manager(&client_);

  for (size_t test = 0; test < base::size(gurls); ++test) {
    manager.DidNavigateMainFrame(gurls[test]);
    for (size_t i = 0; i < input[test].size(); ++i) {
      base::string16 expected_input = input[test].substr(0, i + 1);
      if (expected_input.size() > kMaxNumberOfCharactersToStore)
        expected_input = expected_input.substr(expected_input.size() -
                                               kMaxNumberOfCharactersToStore);
      EXPECT_CALL(
          *store_,
          CheckReuse(expected_input, gurls[test].GetOrigin().spec(), &manager));
      manager.OnKeyPressed(input[test].substr(i, 1));
      testing::Mock::VerifyAndClearExpectations(store_.get());
    }
  }
}

// Verify that the keystroke buffer is cleared after 10 seconds of user
// inactivity.
TEST_F(PasswordReuseDetectionManagerTest,
       CheckThatBufferClearedAfterInactivity) {
  EXPECT_CALL(client_, GetPasswordStore())
      .WillRepeatedly(testing::Return(store_.get()));
  PasswordReuseDetectionManager manager(&client_);

  base::SimpleTestClock clock;
  base::Time now = base::Time::Now();
  clock.SetNow(now);
  manager.SetClockForTesting(&clock);

  EXPECT_CALL(*store_, CheckReuse(base::ASCIIToUTF16("1"), _, _));
  manager.OnKeyPressed(base::ASCIIToUTF16("1"));

  // Simulate 10 seconds of inactivity.
  clock.SetNow(now + base::TimeDelta::FromSeconds(10));
  // Expect that a keystroke typed before inactivity is cleared.
  EXPECT_CALL(*store_, CheckReuse(base::ASCIIToUTF16("2"), _, _));
  manager.OnKeyPressed(base::ASCIIToUTF16("2"));
}

// Verify that the keystroke buffer is cleared after user presses enter.
TEST_F(PasswordReuseDetectionManagerTest, CheckThatBufferClearedAfterEnter) {
  EXPECT_CALL(client_, GetPasswordStore())
      .WillRepeatedly(testing::Return(store_.get()));
  PasswordReuseDetectionManager manager(&client_);

  EXPECT_CALL(*store_, CheckReuse(base::ASCIIToUTF16("1"), _, _));
  manager.OnKeyPressed(base::ASCIIToUTF16("1"));

  base::string16 enter_text(1, ui::VKEY_RETURN);
  EXPECT_CALL(*store_, CheckReuse(_, _, _)).Times(0);
  manager.OnKeyPressed(enter_text);

  // Expect only a keystroke typed after enter.
  EXPECT_CALL(*store_, CheckReuse(base::ASCIIToUTF16("2"), _, _));
  manager.OnKeyPressed(base::ASCIIToUTF16("2"));
}

// Verify that after reuse found, no reuse checking happens till next main frame
// navigation.
TEST_F(PasswordReuseDetectionManagerTest, NoReuseCheckingAfterReuseFound) {
  EXPECT_CALL(client_, GetPasswordStore())
      .WillRepeatedly(testing::Return(store_.get()));
  PasswordReuseDetectionManager manager(&client_);

  // Simulate that reuse found.
  manager.OnReuseFound(0ul, base::nullopt, {"https://example.com"}, 0);

  // Expect no checking of reuse.
  EXPECT_CALL(*store_, CheckReuse(_, _, _)).Times(0);
  manager.OnKeyPressed(base::ASCIIToUTF16("1"));

  // Expect that after main frame navigation checking is restored.
  manager.DidNavigateMainFrame(GURL("https://www.example.com"));
  EXPECT_CALL(*store_, CheckReuse(base::ASCIIToUTF16("1"), _, _));
  manager.OnKeyPressed(base::ASCIIToUTF16("1"));
}

// Verify that keystroke buffer is cleared only on cross host navigation.
TEST_F(PasswordReuseDetectionManagerTest, DidNavigateMainFrame) {
  EXPECT_CALL(client_, GetPasswordStore())
      .WillRepeatedly(testing::Return(store_.get()));
  PasswordReuseDetectionManager manager(&client_);

  manager.DidNavigateMainFrame(GURL("https://www.example1.com/123"));
  EXPECT_CALL(*store_, CheckReuse(base::ASCIIToUTF16("1"), _, _));
  manager.OnKeyPressed(base::ASCIIToUTF16("1"));

  // Check that the buffer is not cleared on the same host navigation.
  manager.DidNavigateMainFrame(GURL("https://www.example1.com/456"));
  EXPECT_CALL(*store_, CheckReuse(base::ASCIIToUTF16("12"), _, _));
  manager.OnKeyPressed(base::ASCIIToUTF16("2"));

  // Check that the buffer is cleared on the cross host navigation.
  manager.DidNavigateMainFrame(GURL("https://www.example2.com/123"));
  EXPECT_CALL(*store_, CheckReuse(base::ASCIIToUTF16("3"), _, _));
  manager.OnKeyPressed(base::ASCIIToUTF16("3"));
}

}  // namespace

}  // namespace password_manager
