blob: c9d30ea2741b943fdbf6ca6f09598c9fc892fa94 [file] [log] [blame]
// 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 "ash/api/tasks/fake_tasks_client.h"
#include <list>
#include <memory>
#include <utility>
#include "ash/api/tasks/tasks_client.h"
#include "ash/api/tasks/tasks_types.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_forward.h"
#include "base/notreached.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "base/uuid.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace ash::api {
namespace {
size_t RunPendingCallbacks(std::list<base::OnceClosure>& pending_callbacks) {
std::list<base::OnceClosure> callbacks;
pending_callbacks.swap(callbacks);
for (auto& callback : callbacks) {
std::move(callback).Run();
}
return callbacks.size();
}
} // namespace
FakeTasksClient::FakeTasksClient(base::Time tasks_due_time) {
PopulateTasks(tasks_due_time);
PopulateTaskLists(tasks_due_time);
}
FakeTasksClient::~FakeTasksClient() = default;
void FakeTasksClient::GetTaskLists(bool force_fetch,
GetTaskListsCallback callback) {
if (!paused_) {
std::move(callback).Run(/*succes=*/true, task_lists_.get());
} else {
pending_get_task_lists_callbacks_.push_back(base::BindOnce(
[](ui::ListModel<TaskList>* task_lists, GetTaskListsCallback callback) {
std::move(callback).Run(/*success=*/true, task_lists);
},
task_lists_.get(), std::move(callback)));
}
}
void FakeTasksClient::GetTasks(const std::string& task_list_id,
bool force_fetch,
GetTasksCallback callback) {
auto iter = tasks_in_task_lists_.find(task_list_id);
CHECK(iter != tasks_in_task_lists_.end());
if (!paused_) {
std::move(callback).Run(/*success=*/true, iter->second.get());
} else {
pending_get_tasks_callbacks_.push_back(base::BindOnce(
[](ui::ListModel<Task>* tasks, GetTasksCallback callback) {
std::move(callback).Run(/*success=*/true, tasks);
},
iter->second.get(), std::move(callback)));
}
}
void FakeTasksClient::MarkAsCompleted(const std::string& task_list_id,
const std::string& task_id,
bool completed) {
if (completed) {
pending_completed_tasks_.push_back(
base::JoinString({task_list_id, task_id}, ":"));
} else {
pending_completed_tasks_.erase(
base::ranges::find(pending_completed_tasks_,
base::JoinString({task_list_id, task_id}, ":")));
}
}
void FakeTasksClient::AddTask(const std::string& task_list_id,
const std::string& title,
TasksClient::OnTaskSavedCallback callback) {
if (paused_) {
pending_add_task_callbacks_.push_back(
base::BindOnce(&FakeTasksClient::AddTaskImpl, base::Unretained(this),
task_list_id, title, std::move(callback)));
} else {
AddTaskImpl(task_list_id, title, std::move(callback));
}
}
void FakeTasksClient::UpdateTask(const std::string& task_list_id,
const std::string& task_id,
const std::string& title,
bool completed,
TasksClient::OnTaskSavedCallback callback) {
if (paused_) {
pending_update_task_callbacks_.push_back(base::BindOnce(
&FakeTasksClient::UpdateTaskImpl, base::Unretained(this), task_list_id,
task_id, title, completed, std::move(callback)));
} else {
UpdateTaskImpl(task_list_id, task_id, title, completed,
std::move(callback));
}
}
void FakeTasksClient::OnGlanceablesBubbleClosed(
TasksClient::OnAllPendingCompletedTasksSavedCallback callback) {
++bubble_closed_count_;
RunPendingGetTaskListsCallbacks();
RunPendingGetTasksCallbacks();
RunPendingAddTaskCallbacks();
RunPendingUpdateTaskCallbacks();
completed_tasks_ += pending_completed_tasks_.size();
pending_completed_tasks_.clear();
std::move(callback).Run();
}
int FakeTasksClient::GetAndResetBubbleClosedCount() {
int result = bubble_closed_count_;
bubble_closed_count_ = 0;
return result;
}
size_t FakeTasksClient::RunPendingGetTasksCallbacks() {
return RunPendingCallbacks(pending_get_tasks_callbacks_);
}
size_t FakeTasksClient::RunPendingGetTaskListsCallbacks() {
return RunPendingCallbacks(pending_get_task_lists_callbacks_);
}
size_t FakeTasksClient::RunPendingAddTaskCallbacks() {
return RunPendingCallbacks(pending_add_task_callbacks_);
}
size_t FakeTasksClient::RunPendingUpdateTaskCallbacks() {
return RunPendingCallbacks(pending_update_task_callbacks_);
}
void FakeTasksClient::AddTaskImpl(const std::string& task_list_id,
const std::string& title,
TasksClient::OnTaskSavedCallback callback) {
if (run_with_errors_) {
std::move(callback).Run(/*task=*/nullptr);
return;
}
auto task_list_iter = tasks_in_task_lists_.find(task_list_id);
CHECK(task_list_iter != tasks_in_task_lists_.end());
auto pending_task = std::make_unique<Task>(
base::Uuid::GenerateRandomV4().AsLowercaseString(), title,
/*due=*/absl::nullopt, /*completed=*/false,
/*has_subtasks=*/false, /*has_email_link=*/false,
/*has_notes=*/false,
/*updated=*/base::Time::Now());
const auto* const task = task_list_iter->second->AddAt(
/*index=*/0, std::move(pending_task));
std::move(callback).Run(task);
}
void FakeTasksClient::UpdateTaskImpl(
const std::string& task_list_id,
const std::string& task_id,
const std::string& title,
bool completed,
TasksClient::OnTaskSavedCallback callback) {
if (run_with_errors_) {
std::move(callback).Run(/*task=*/nullptr);
return;
}
auto task_list_iter = tasks_in_task_lists_.find(task_list_id);
CHECK(task_list_iter != tasks_in_task_lists_.end());
const auto task_iter = std::find_if(
task_list_iter->second->begin(), task_list_iter->second->end(),
[&task_id](const auto& task) { return task->id == task_id; });
CHECK(task_iter != task_list_iter->second->end());
Task* task = task_iter->get();
task->title = title;
task->completed = completed;
std::move(callback).Run(task);
}
void FakeTasksClient::PopulateTasks(base::Time tasks_due_time) {
task_lists_ = std::make_unique<ui::ListModel<TaskList>>();
task_lists_->Add(std::make_unique<TaskList>(
"TaskListID1", "Task List 1 Title", /*updated=*/tasks_due_time));
task_lists_->Add(std::make_unique<TaskList>(
"TaskListID2", "Task List 2 Title", /*updated=*/tasks_due_time));
task_lists_->Add(std::make_unique<TaskList>("TaskListID3",
"Task List 3 Title (empty)",
/*updated=*/tasks_due_time));
task_lists_->Add(std::make_unique<TaskList>("TaskListID4",
"Task List 4 Title (empty)",
/*updated=*/tasks_due_time));
task_lists_->Add(std::make_unique<TaskList>("TaskListID5",
"Task List 5 Title (empty)",
/*updated=*/tasks_due_time));
task_lists_->Add(std::make_unique<TaskList>("TaskListID6",
"Task List 6 Title (empty)",
/*updated=*/tasks_due_time));
}
void FakeTasksClient::PopulateTaskLists(base::Time tasks_due_time) {
std::unique_ptr<ui::ListModel<Task>> task_list_1 =
std::make_unique<ui::ListModel<Task>>();
task_list_1->Add(std::make_unique<Task>(
"TaskListItem1", "Task List 1 Item 1 Title",
/*due=*/tasks_due_time, /*completed=*/false,
/*has_subtasks=*/false, /*has_email_link=*/false, /*has_notes=*/false,
/*updated=*/tasks_due_time));
task_list_1->Add(std::make_unique<Task>(
"TaskListItem2", "Task List 1 Item 2 Title",
/*due=*/tasks_due_time, /*completed=*/false,
/*has_subtasks=*/false, /*has_email_link=*/false, /*has_notes=*/false,
/*updated=*/tasks_due_time));
std::unique_ptr<ui::ListModel<Task>> task_list_2 =
std::make_unique<ui::ListModel<Task>>();
task_list_2->Add(std::make_unique<Task>(
"TaskListItem3", "Task List 2 Item 1 Title",
/*due=*/tasks_due_time, /*completed=*/false,
/*has_subtasks=*/false, /*has_email_link=*/false, /*has_notes=*/false,
/*updated=*/tasks_due_time));
task_list_2->Add(std::make_unique<Task>(
"TaskListItem4", "Task List 2 Item 2 Title",
/*due=*/tasks_due_time, /*completed=*/false,
/*has_subtasks=*/false, /*has_email_link=*/false, /*has_notes=*/false,
/*updated=*/tasks_due_time));
task_list_2->Add(std::make_unique<Task>(
"TaskListItem5", "Task List 2 Item 3 Title",
/*due=*/tasks_due_time, /*completed=*/false,
/*has_subtasks=*/false, /*has_email_link=*/false, /*has_notes=*/false,
/*updated=*/tasks_due_time));
tasks_in_task_lists_.emplace("TaskListID1", std::move(task_list_1));
tasks_in_task_lists_.emplace("TaskListID2", std::move(task_list_2));
tasks_in_task_lists_.emplace("TaskListID3",
std::make_unique<ui::ListModel<Task>>());
tasks_in_task_lists_.emplace("TaskListID4",
std::make_unique<ui::ListModel<Task>>());
tasks_in_task_lists_.emplace("TaskListID5",
std::make_unique<ui::ListModel<Task>>());
tasks_in_task_lists_.emplace("TaskListID6",
std::make_unique<ui::ListModel<Task>>());
}
} // namespace ash::api