chromium/chrome/browser/ash/crosapi/desk_ash_unittest.cc

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/crosapi/desk_ash.h"

#include <memory>

#include "ash/wm/desks/desk.h"
#include "base/test/repeating_test_future.h"
#include "base/test/test_future.h"
#include "base/types/expected.h"
#include "base/uuid.h"
#include "chrome/browser/ui/ash/desks/desks_client.h"
#include "chromeos/crosapi/mojom/desk.mojom-forward.h"
#include "chromeos/crosapi/mojom/desk.mojom.h"
#include "content/public/test/browser_task_environment.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "testing/gmock/include/gmock/gmock.h"

using ::testing::_;

namespace crosapi {

class MockDesksClient : public DesksClient {
 public:
  MOCK_METHOD((base::expected<const ash::Desk*, DesksClient::DeskActionError>),
              GetDeskByID,
              (const base::Uuid&),
              (const));
};

class TestDeskEventObserver : public crosapi::mojom::DeskEventObserver {
 public:
  void OnDeskSwitched(const base::Uuid& new_desk_id,
                      const base::Uuid& previous_desk_id) override {
    event_future_.AddValue(new_desk_id);
    event_future_.AddValue(previous_desk_id);
  }
  void OnDeskAdded(const base::Uuid& new_desk_id, bool from_undo) override {
    event_future_.AddValue(new_desk_id);
  }
  void OnDeskRemoved(const base::Uuid& removed_desk_id) override {
    event_future_.AddValue(removed_desk_id);
  }

  mojo::PendingRemote<crosapi::mojom::DeskEventObserver> GetRemote() {
    return receiver_.BindNewPipeAndPassRemote();
  }
  mojo::Receiver<crosapi::mojom::DeskEventObserver>& GetReceiver() {
    return receiver_;
  }
  base::Uuid WaitAndGet() { return event_future_.Take(); }

 private:
  mojo::Receiver<crosapi::mojom::DeskEventObserver> receiver_{this};
  base::test::RepeatingTestFuture<base::Uuid> event_future_;
};

class DeskAshTest : public testing::Test {
 public:
  DeskAshTest() = default;
  ~DeskAshTest() override = default;

  void SetUp() override {
    desk_ash_ = std::make_unique<DeskAsh>();
    desk_ash_->BindReceiver(desk_ash_remote_.BindNewPipeAndPassReceiver());
  }

  MockDesksClient& mock_desks_client() { return mock_desks_client_; }
  TestDeskEventObserver& desk_event_observer() { return desk_event_observer_; }

 protected:
  content::BrowserTaskEnvironment task_environment_;
  mojo::Remote<mojom::Desk> desk_ash_remote_;
  std::unique_ptr<DeskAsh> desk_ash_;

 private:
  testing::NiceMock<MockDesksClient> mock_desks_client_;
  TestDeskEventObserver desk_event_observer_;
};

TEST_F(DeskAshTest, GetDeskByIDWithInvalidIDTest) {
  ASSERT_EQ(&mock_desks_client(), DesksClient::Get());
  base::Uuid fake_id;
  EXPECT_CALL(mock_desks_client(), GetDeskByID(fake_id))
      .Times(1)
      .WillOnce(testing::Return(
          base::unexpected(DesksClient::DeskActionError::kInvalidIdError)));

  base::test::TestFuture<mojom::GetDeskByIDResultPtr> future;
  desk_ash_remote_->GetDeskByID(fake_id, future.GetCallback());
  auto result = future.Take();
  ASSERT_TRUE(result->is_error());
  EXPECT_EQ(crosapi::mojom::DeskCrosApiError::kInvalidIdError,
            result->get_error());
}

TEST_F(DeskAshTest, NotifyDeskAddedTest) {
  desk_ash_remote_->AddDeskEventObserver(desk_event_observer().GetRemote());
  // Flush pipe so that registration shows up.
  desk_ash_remote_.FlushForTesting();
  desk_event_observer().GetReceiver().FlushForTesting();
  auto desk_id(base::Uuid::GenerateRandomV4());
  desk_ash_->NotifyDeskAdded(desk_id);

  EXPECT_EQ(desk_event_observer().WaitAndGet(), desk_id);
}

TEST_F(DeskAshTest, NotifyDeskRemovedTest) {
  desk_ash_remote_->AddDeskEventObserver(desk_event_observer().GetRemote());
  // Flush pipe so that registration shows up.
  desk_ash_remote_.FlushForTesting();
  desk_event_observer().GetReceiver().FlushForTesting();
  auto desk_id(base::Uuid::GenerateRandomV4());
  desk_ash_->NotifyDeskRemoved(desk_id);

  EXPECT_EQ(desk_event_observer().WaitAndGet(), desk_id);
}

TEST_F(DeskAshTest, NotifyDeskSwitchedTest) {
  desk_ash_remote_->AddDeskEventObserver(desk_event_observer().GetRemote());
  // Flush pipe so that registration shows up.
  desk_ash_remote_.FlushForTesting();
  desk_event_observer().GetReceiver().FlushForTesting();
  auto old_id(base::Uuid::GenerateRandomV4());
  auto new_id(base::Uuid::GenerateRandomV4());

  desk_ash_->NotifyDeskSwitched(new_id, old_id);

  EXPECT_EQ(desk_event_observer().WaitAndGet(), new_id);
  EXPECT_EQ(desk_event_observer().WaitAndGet(), old_id);
}

TEST_F(DeskAshTest, NotifyDeskRemovalUndoneTest) {
  desk_ash_remote_->AddDeskEventObserver(desk_event_observer().GetRemote());
  // Flush pipe so that registration shows up.
  desk_ash_remote_.FlushForTesting();
  desk_event_observer().GetReceiver().FlushForTesting();
  auto desk_id(base::Uuid::GenerateRandomV4());
  desk_ash_->NotifyDeskAdded(desk_id, true);

  EXPECT_EQ(desk_event_observer().WaitAndGet(), desk_id);
}

}  // namespace crosapi