// Copyright 2014 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.

#include "debugd/src/dev_mode_no_owner_restriction.h"

#include <gtest/gtest.h>

namespace debugd {

namespace {

// Test class to fake different system state conditions.
class FakeDevModeNoOwnerRestriction : public DevModeNoOwnerRestriction {
 public:
  FakeDevModeNoOwnerRestriction()
      : DevModeNoOwnerRestriction(nullptr),
        fake_boot_lockbox_finalized_(false),
        fake_cryptohome_access_(false),
        fake_in_dev_mode_(false),
        fake_owner_user_exists_(false) {}

  ~FakeDevModeNoOwnerRestriction() override = default;

  // Functions to set the fake system state.
  void set_fake_boot_lockbox_finalized(bool fake_boot_lockbox_finalized) {
    fake_boot_lockbox_finalized_ = fake_boot_lockbox_finalized;
  }
  void set_fake_cryptohome_access(bool fake_cryptohome_access) {
    fake_cryptohome_access_ = fake_cryptohome_access;
  }
  void set_fake_in_dev_mode_(bool fake_in_dev_mode) {
    fake_in_dev_mode_ = fake_in_dev_mode;
  }
  void set_fake_owner_user_exists(bool fake_owner_user_exists) {
    fake_owner_user_exists_ = fake_owner_user_exists;
  }

 private:
  bool fake_boot_lockbox_finalized_;
  bool fake_cryptohome_access_;
  bool fake_in_dev_mode_;
  bool fake_owner_user_exists_;

  // Reports the fake dev mode state.
  bool InDevMode() const override { return fake_in_dev_mode_; }

  // Reports the fake owner and lockbox states.
  bool GetOwnerAndLockboxStatus(bool* owner_user_exists,
                                bool* boot_lockbox_finalized) override {
    if (fake_cryptohome_access_) {
      *owner_user_exists = fake_owner_user_exists_;
      *boot_lockbox_finalized = fake_boot_lockbox_finalized_;
    }
    return fake_cryptohome_access_;
  }
};

}  // namespace

class DevModeNoOwnerRestrictionTest : public ::testing::Test {
 public:
  DevModeNoOwnerRestrictionTest() {
    // By default configure FakeDevModeNoOwnerRestriction to allow access.
    restriction_.set_fake_in_dev_mode_(true);
    restriction_.set_fake_cryptohome_access(true);
    restriction_.set_fake_boot_lockbox_finalized(false);
    restriction_.set_fake_owner_user_exists(false);
  }

  ~DevModeNoOwnerRestrictionTest() override = default;

 protected:
  FakeDevModeNoOwnerRestriction restriction_;
};

TEST_F(DevModeNoOwnerRestrictionTest, AllowUse) {
  EXPECT_TRUE(restriction_.AllowToolUse(nullptr));
}

TEST_F(DevModeNoOwnerRestrictionTest, DisallowUseNonDevmode) {
  restriction_.set_fake_in_dev_mode_(false);
  EXPECT_FALSE(restriction_.AllowToolUse(nullptr));
}

TEST_F(DevModeNoOwnerRestrictionTest, DisallowUseNoCryptohome) {
  restriction_.set_fake_cryptohome_access(false);
  EXPECT_FALSE(restriction_.AllowToolUse(nullptr));
}

TEST_F(DevModeNoOwnerRestrictionTest, DisallowUseBootLockboxFinalized) {
  restriction_.set_fake_boot_lockbox_finalized(true);
  EXPECT_FALSE(restriction_.AllowToolUse(nullptr));
}

TEST_F(DevModeNoOwnerRestrictionTest, DisallowUseOwnerExists) {
  restriction_.set_fake_owner_user_exists(true);
  EXPECT_FALSE(restriction_.AllowToolUse(nullptr));
}

}  // namespace debugd
