Files
panopainter/tests/app_core/document_cloud_tests.cpp

334 lines
14 KiB
C++

#include "app_core/document_cloud.h"
#include "test_harness.h"
#include <limits>
#include <string>
namespace {
class FakeCloudServices final : public pp::app::CloudServices {
public:
void show_save_required_warning() override
{
warnings += 1;
call_order += "warn;";
}
void prompt_publish(bool save_before_upload) override
{
prompts += 1;
last_save_before_upload = save_before_upload;
call_order += "prompt;";
}
void begin_bulk_upload(int progress_total, bool show_progress) override
{
bulk_begins += 1;
last_progress_total = progress_total;
last_show_progress = show_progress;
call_order += "begin;";
}
void upload_all_bulk_files() override
{
bulk_uploads += 1;
call_order += "upload-all;";
}
void end_bulk_upload() override
{
bulk_ends += 1;
call_order += "end;";
}
void show_browser() override
{
browsers += 1;
call_order += "browse;";
}
void start_download(const pp::app::CloudDownloadRequest& request) override
{
downloads += 1;
last_selected_file = request.selected_file;
last_selected_path = request.selected_path;
last_selected_name = request.selected_name;
call_order += "download;";
}
int warnings = 0;
int prompts = 0;
int bulk_begins = 0;
int bulk_uploads = 0;
int bulk_ends = 0;
int browsers = 0;
int downloads = 0;
int last_progress_total = 0;
bool last_save_before_upload = false;
bool last_show_progress = false;
std::string last_selected_file;
std::string last_selected_path;
std::string last_selected_name;
std::string call_order;
};
void cloud_upload_is_unavailable_without_canvas(pp::tests::Harness& harness)
{
const auto plan = pp::app::plan_cloud_upload(false, false, false);
PP_EXPECT(harness, plan.action == pp::app::CloudUploadAction::unavailable_no_canvas);
PP_EXPECT(harness, !plan.save_before_upload);
}
void cloud_upload_warns_for_new_documents(pp::tests::Harness& harness)
{
const auto plan = pp::app::plan_cloud_upload(true, true, true);
PP_EXPECT(harness, plan.action == pp::app::CloudUploadAction::show_save_required_warning);
PP_EXPECT(harness, !plan.save_before_upload);
}
void cloud_upload_prompts_for_clean_existing_documents(pp::tests::Harness& harness)
{
const auto plan = pp::app::plan_cloud_upload(true, false, false);
PP_EXPECT(harness, plan.action == pp::app::CloudUploadAction::prompt_publish);
PP_EXPECT(harness, !plan.save_before_upload);
}
void cloud_upload_records_save_before_upload_for_dirty_existing_documents(pp::tests::Harness& harness)
{
const auto plan = pp::app::plan_cloud_upload(true, false, true);
PP_EXPECT(harness, plan.action == pp::app::CloudUploadAction::prompt_publish);
PP_EXPECT(harness, plan.save_before_upload);
}
void cloud_browse_is_unavailable_without_canvas(pp::tests::Harness& harness)
{
PP_EXPECT(harness, pp::app::plan_cloud_browse(false) == pp::app::CloudBrowseAction::unavailable_no_canvas);
}
void cloud_browse_shows_browser_with_canvas(pp::tests::Harness& harness)
{
PP_EXPECT(harness, pp::app::plan_cloud_browse(true) == pp::app::CloudBrowseAction::show_browser);
}
void cloud_download_selection_waits_for_empty_file(pp::tests::Harness& harness)
{
PP_EXPECT(
harness,
pp::app::plan_cloud_download_selection("") == pp::app::CloudDownloadSelectionAction::wait_for_selection);
}
void cloud_download_selection_starts_for_selected_file(pp::tests::Harness& harness)
{
PP_EXPECT(
harness,
pp::app::plan_cloud_download_selection("demo.ppi") == pp::app::CloudDownloadSelectionAction::start_download);
}
void cloud_bulk_upload_shows_progress_when_ui_available(pp::tests::Harness& harness)
{
const auto plan = pp::app::plan_cloud_bulk_upload(3, true);
PP_EXPECT(harness, plan.file_count == 3);
PP_EXPECT(harness, plan.progress_total == 3);
PP_EXPECT(harness, plan.show_progress);
}
void cloud_bulk_upload_runs_without_progress_when_ui_unavailable(pp::tests::Harness& harness)
{
const auto plan = pp::app::plan_cloud_bulk_upload(3, false);
PP_EXPECT(harness, plan.file_count == 3);
PP_EXPECT(harness, plan.progress_total == 3);
PP_EXPECT(harness, !plan.show_progress);
}
void cloud_bulk_upload_keeps_zero_file_progress_explicit(pp::tests::Harness& harness)
{
const auto plan = pp::app::plan_cloud_bulk_upload(0, true);
PP_EXPECT(harness, plan.file_count == 0);
PP_EXPECT(harness, plan.progress_total == 0);
PP_EXPECT(harness, plan.show_progress);
}
void cloud_bulk_upload_clamps_progress_total(pp::tests::Harness& harness)
{
const auto too_many_files = static_cast<std::size_t>(std::numeric_limits<int>::max()) + 1U;
const auto plan = pp::app::plan_cloud_bulk_upload(too_many_files, true);
PP_EXPECT(harness, plan.file_count == too_many_files);
PP_EXPECT(harness, plan.progress_total == std::numeric_limits<int>::max());
PP_EXPECT(harness, plan.show_progress);
}
void cloud_download_transfer_rejects_missing_url(pp::tests::Harness& harness)
{
const auto plan = pp::app::plan_cloud_download_transfer("", "D:/Paint/demo.ppi", true, true);
PP_EXPECT(harness, plan.direction == pp::app::CloudTransferDirection::download);
PP_EXPECT(harness, plan.action == pp::app::CloudTransferAction::reject_missing_source);
PP_EXPECT(harness, !plan.enable_progress);
PP_EXPECT(harness, !plan.disable_tls_verification);
}
void cloud_download_transfer_rejects_missing_destination(pp::tests::Harness& harness)
{
const auto plan = pp::app::plan_cloud_download_transfer("https://example.invalid/demo.ppi", "", true, true);
PP_EXPECT(harness, plan.direction == pp::app::CloudTransferDirection::download);
PP_EXPECT(harness, plan.action == pp::app::CloudTransferAction::reject_missing_destination);
PP_EXPECT(harness, !plan.enable_progress);
PP_EXPECT(harness, !plan.disable_tls_verification);
}
void cloud_download_transfer_starts_with_progress_and_tls_policy(pp::tests::Harness& harness)
{
const auto plan = pp::app::plan_cloud_download_transfer(
"https://example.invalid/demo.ppi",
"D:/Paint/demo.ppi",
true,
true);
PP_EXPECT(harness, plan.direction == pp::app::CloudTransferDirection::download);
PP_EXPECT(harness, plan.action == pp::app::CloudTransferAction::start_transfer);
PP_EXPECT(harness, plan.enable_progress);
PP_EXPECT(harness, plan.disable_tls_verification);
}
void cloud_upload_transfer_rejects_missing_file(pp::tests::Harness& harness)
{
const auto plan = pp::app::plan_cloud_upload_transfer("", true, true);
PP_EXPECT(harness, plan.direction == pp::app::CloudTransferDirection::upload);
PP_EXPECT(harness, plan.action == pp::app::CloudTransferAction::reject_missing_source);
PP_EXPECT(harness, !plan.enable_progress);
PP_EXPECT(harness, !plan.disable_tls_verification);
}
void cloud_upload_transfer_starts_with_progress_and_tls_policy(pp::tests::Harness& harness)
{
const auto plan = pp::app::plan_cloud_upload_transfer("D:/Paint/demo.ppi", true, false);
PP_EXPECT(harness, plan.direction == pp::app::CloudTransferDirection::upload);
PP_EXPECT(harness, plan.action == pp::app::CloudTransferAction::start_transfer);
PP_EXPECT(harness, plan.enable_progress);
PP_EXPECT(harness, !plan.disable_tls_verification);
}
void cloud_transfer_progress_ignores_unknown_total(pp::tests::Harness& harness)
{
const auto zero = pp::app::plan_cloud_transfer_progress(0, 4);
const auto negative = pp::app::plan_cloud_transfer_progress(-10, 4);
PP_EXPECT(harness, !zero.notify);
PP_EXPECT(harness, zero.fraction == 0.0F);
PP_EXPECT(harness, !negative.notify);
PP_EXPECT(harness, negative.fraction == 0.0F);
}
void cloud_transfer_progress_clamps_to_valid_fraction(pp::tests::Harness& harness)
{
const auto before_start = pp::app::plan_cloud_transfer_progress(10, -2);
const auto half = pp::app::plan_cloud_transfer_progress(10, 5);
const auto after_end = pp::app::plan_cloud_transfer_progress(10, 20);
PP_EXPECT(harness, before_start.notify);
PP_EXPECT(harness, before_start.fraction == 0.0F);
PP_EXPECT(harness, half.notify);
PP_EXPECT(harness, half.fraction == 0.5F);
PP_EXPECT(harness, after_end.notify);
PP_EXPECT(harness, after_end.fraction == 1.0F);
}
void executor_dispatches_cloud_upload_variants(pp::tests::Harness& harness)
{
FakeCloudServices services;
PP_EXPECT(harness, pp::app::execute_cloud_upload_plan(pp::app::plan_cloud_upload(false, false, false), services).ok());
PP_EXPECT(harness, pp::app::execute_cloud_upload_plan(pp::app::plan_cloud_upload(true, true, true), services).ok());
PP_EXPECT(harness, pp::app::execute_cloud_upload_plan(pp::app::plan_cloud_upload(true, false, true), services).ok());
PP_EXPECT(harness, services.warnings == 1);
PP_EXPECT(harness, services.prompts == 1);
PP_EXPECT(harness, services.last_save_before_upload);
PP_EXPECT(harness, services.call_order == "warn;prompt;");
}
void executor_dispatches_cloud_bulk_browse_and_download(pp::tests::Harness& harness)
{
FakeCloudServices services;
const auto bulk = pp::app::plan_cloud_bulk_upload(3, true);
PP_EXPECT(harness, pp::app::execute_cloud_bulk_upload_plan(bulk, services).ok());
PP_EXPECT(harness, pp::app::execute_cloud_browse_action(pp::app::plan_cloud_browse(false), services).ok());
PP_EXPECT(harness, pp::app::execute_cloud_browse_action(pp::app::plan_cloud_browse(true), services).ok());
pp::app::CloudDownloadRequest wait_request;
PP_EXPECT(
harness,
pp::app::execute_cloud_download_selection_action(
pp::app::plan_cloud_download_selection(""),
services,
wait_request)
.ok());
pp::app::CloudDownloadRequest download_request {
.selected_file = "demo.ppi",
.selected_path = "D:/Paint/demo.ppi",
.selected_name = "demo",
};
PP_EXPECT(
harness,
pp::app::execute_cloud_download_selection_action(
pp::app::plan_cloud_download_selection(download_request.selected_file),
services,
download_request)
.ok());
PP_EXPECT(harness, services.bulk_begins == 1);
PP_EXPECT(harness, services.last_progress_total == 3);
PP_EXPECT(harness, services.last_show_progress);
PP_EXPECT(harness, services.bulk_uploads == 1);
PP_EXPECT(harness, services.bulk_ends == 1);
PP_EXPECT(harness, services.browsers == 1);
PP_EXPECT(harness, services.downloads == 1);
PP_EXPECT(harness, services.last_selected_file == "demo.ppi");
PP_EXPECT(harness, services.last_selected_path == "D:/Paint/demo.ppi");
PP_EXPECT(harness, services.last_selected_name == "demo");
PP_EXPECT(harness, services.call_order == "begin;upload-all;end;browse;download;");
}
void executor_rejects_mismatched_download_action(pp::tests::Harness& harness)
{
FakeCloudServices services;
pp::app::CloudDownloadRequest empty_request;
PP_EXPECT(
harness,
!pp::app::execute_cloud_download_selection_action(
pp::app::CloudDownloadSelectionAction::start_download,
services,
empty_request)
.ok());
PP_EXPECT(harness, services.downloads == 0);
}
}
int main()
{
pp::tests::Harness harness;
harness.run("cloud upload is unavailable without canvas", cloud_upload_is_unavailable_without_canvas);
harness.run("cloud upload warns for new documents", cloud_upload_warns_for_new_documents);
harness.run("cloud upload prompts for clean existing documents", cloud_upload_prompts_for_clean_existing_documents);
harness.run("cloud upload records save before upload for dirty existing documents", cloud_upload_records_save_before_upload_for_dirty_existing_documents);
harness.run("cloud browse is unavailable without canvas", cloud_browse_is_unavailable_without_canvas);
harness.run("cloud browse shows browser with canvas", cloud_browse_shows_browser_with_canvas);
harness.run("cloud download selection waits for empty file", cloud_download_selection_waits_for_empty_file);
harness.run("cloud download selection starts for selected file", cloud_download_selection_starts_for_selected_file);
harness.run("cloud bulk upload shows progress when ui available", cloud_bulk_upload_shows_progress_when_ui_available);
harness.run("cloud bulk upload runs without progress when ui unavailable", cloud_bulk_upload_runs_without_progress_when_ui_unavailable);
harness.run("cloud bulk upload keeps zero file progress explicit", cloud_bulk_upload_keeps_zero_file_progress_explicit);
harness.run("cloud bulk upload clamps progress total", cloud_bulk_upload_clamps_progress_total);
harness.run("cloud download transfer rejects missing url", cloud_download_transfer_rejects_missing_url);
harness.run("cloud download transfer rejects missing destination", cloud_download_transfer_rejects_missing_destination);
harness.run("cloud download transfer starts with progress and tls policy", cloud_download_transfer_starts_with_progress_and_tls_policy);
harness.run("cloud upload transfer rejects missing file", cloud_upload_transfer_rejects_missing_file);
harness.run("cloud upload transfer starts with progress and tls policy", cloud_upload_transfer_starts_with_progress_and_tls_policy);
harness.run("cloud transfer progress ignores unknown total", cloud_transfer_progress_ignores_unknown_total);
harness.run("cloud transfer progress clamps to valid fraction", cloud_transfer_progress_clamps_to_valid_fraction);
harness.run("executor dispatches cloud upload variants", executor_dispatches_cloud_upload_variants);
harness.run("executor dispatches cloud bulk browse and download", executor_dispatches_cloud_bulk_browse_and_download);
harness.run("executor rejects mismatched download action", executor_rejects_mismatched_download_action);
return harness.finish();
}