chromium/ui/base/clipboard/clipboard_non_backed_unittest.cc

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

#include "ui/base/clipboard/clipboard_non_backed.h"

#include <memory>
#include <string>
#include <vector>

#include "base/pickle.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/task_environment.h"
#include "base/test/test_future.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/clipboard/clipboard_data.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/image/image_unittest_util.h"
#include "ui/gfx/skia_util.h"

#if BUILDFLAG(IS_OZONE)
#include "base/command_line.h"
#include "ui/gfx/switches.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/ozone/public/ozone_switches.h"
#endif  // BUILDFLAG(IS_OZONE)

namespace ui {
namespace {

std::vector<std::string> UTF8Types(std::vector<std::u16string> types) {}

}  // namespace

// Base class for tests of `ClipboardNonBacked`.
class ClipboardNonBackedTestBase : public testing::Test {};

// Base class for tests of `ClipboardNonBacked` which use system time.
class ClipboardNonBackedTest : public ClipboardNonBackedTestBase {};

// Verifies that GetClipboardData() returns the same instance of ClipboardData
// as was written via WriteClipboardData().
TEST_F(ClipboardNonBackedTest, WriteAndGetClipboardData) {}

// Verifies that WriteClipboardData() writes a ClipboardData instance to the
// clipboard and returns the previous instance.
TEST_F(ClipboardNonBackedTest, WriteClipboardData) {}

// Verifies that directly writing to ClipboardInternal does not result in
// histograms being logged. This is used by ClipboardHistoryController to
// manipulate the clipboard in order to facilitate pasting from clipboard
// history.
TEST_F(ClipboardNonBackedTest, AdminWriteDoesNotRecordHistograms) {}

// Tests that text data uses 'text/plain' mime type.
TEST_F(ClipboardNonBackedTest, PlainText) {}

// Tests that site bookmark URLs are accessed as text, and
// IsFormatAvailable('text/uri-list') is only true for files.
TEST_F(ClipboardNonBackedTest, BookmarkURL) {}

// Filenames data uses mime type 'text/uri-list'.
TEST_F(ClipboardNonBackedTest, TextURIList) {}

// Tests that bitmaps written to the clipboard are read out encoded as a PNG.
TEST_F(ClipboardNonBackedTest, ImageEncoding) {}

// Tests that consecutive calls to read an image from the clipboard only results
// in the image being encoded once.
TEST_F(ClipboardNonBackedTest, EncodeImageOnce) {}

// Tests that consecutive calls to read an image from the clipboard only results
// in the image being encoded once, but if another image is placed on the
// clipboard, this image is appropriately encoded.
TEST_F(ClipboardNonBackedTest, EncodeMultipleImages) {}

// Tests that different clipboard buffers have independent data.
TEST_F(ClipboardNonBackedTest, ClipboardBufferTypes) {}

#if BUILDFLAG(IS_CHROMEOS)
// Base class for tests of `ClipboardNonBacked` which use mock time.
class ClipboardNonBackedMockTimeTest : public ClipboardNonBackedTestBase {
 public:
  ClipboardNonBackedMockTimeTest()
      : ClipboardNonBackedTestBase(
            base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
};

// Verifies that `ClipboardNonBacked` records the time interval between commit
// and read of the same `ClipboardData`.
TEST_F(ClipboardNonBackedMockTimeTest,
       RecordsTimeIntervalBetweenCommitAndRead) {
  // Cache clipboard for the current thread.
  auto* clipboard = ClipboardNonBacked::GetForCurrentThread();
  ASSERT_TRUE(clipboard);

  // Write clipboard data to the clipboard.
  ScopedClipboardWriter(ClipboardBuffer::kCopyPaste).WriteText(u"");
  auto* clipboard_data = clipboard->GetClipboardData(/*data_dst=*/nullptr);
  ASSERT_TRUE(clipboard_data);
  ASSERT_TRUE(clipboard_data->commit_time().has_value());
  EXPECT_EQ(clipboard_data->commit_time().value(), base::Time::Now());

  // This test will verify expectations for every kind of clipboard data read.
  std::vector<base::RepeatingClosure> test_cases = {{
      base::BindLambdaForTesting([&]() {
        clipboard->ReadAsciiText(
            ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr,
            /*result=*/std::make_unique<std::string>().get());
      }),
      base::BindLambdaForTesting([&]() {
        clipboard->ReadBookmark(
            /*data_dst=*/nullptr,
            /*title=*/std::make_unique<std::u16string>().get(),
            /*url=*/std::make_unique<std::string>().get());
      }),
      base::BindLambdaForTesting([&]() {
        clipboard->ReadDataTransferCustomData(
            ClipboardBuffer::kCopyPaste,
            /*type=*/std::u16string(), /*data_dst=*/nullptr,
            /*result=*/std::make_unique<std::u16string>().get());
      }),
      base::BindLambdaForTesting([&]() {
        clipboard->ReadData(ui::ClipboardFormatType(),
                            /*data_dst=*/nullptr,
                            /*result=*/std::make_unique<std::string>().get());
      }),
      base::BindLambdaForTesting([&]() {
        clipboard->ReadFilenames(
            ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr,
            /*result=*/std::make_unique<std::vector<ui::FileInfo>>().get());
      }),
      base::BindLambdaForTesting([&]() {
        clipboard->ReadHTML(
            ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr,
            /*markup=*/std::make_unique<std::u16string>().get(),
            /*src_url=*/std::make_unique<std::string>().get(),
            /*fragment_start=*/std::make_unique<uint32_t>().get(),
            /*fragment_end=*/std::make_unique<uint32_t>().get());
      }),
      base::BindLambdaForTesting([&]() {
        clipboard->ReadPng(ClipboardBuffer::kCopyPaste,
                           /*data_dst=*/nullptr,
                           /*callback=*/base::DoNothing());
      }),
      base::BindLambdaForTesting([&]() {
        clipboard->ReadRTF(ClipboardBuffer::kCopyPaste,
                           /*data_dst=*/nullptr,
                           /*result=*/std::make_unique<std::string>().get());
      }),
      base::BindLambdaForTesting([&]() {
        clipboard->ReadSvg(ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr,
                           /*result=*/std::make_unique<std::u16string>().get());
      }),
      base::BindLambdaForTesting([&]() {
        clipboard->ReadText(
            ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr,
            /*result=*/std::make_unique<std::u16string>().get());
      }),
  }};

  // Read clipboard data and verify histogram expectations.
  constexpr base::TimeDelta kTimeDelta = base::Seconds(10);
  constexpr char kHistogram[] = "Clipboard.TimeIntervalBetweenCommitAndRead";
  for (size_t i = 1u; i <= test_cases.size(); ++i) {
    base::HistogramTester histogram_tester;
    histogram_tester.ExpectUniqueTimeSample(kHistogram, i * kTimeDelta, 0u);
    task_environment_.FastForwardBy(kTimeDelta);
    test_cases.at(i - 1u).Run();
    histogram_tester.ExpectUniqueTimeSample(kHistogram, i * kTimeDelta, 1u);
  }
}
#endif  // BUILDFLAG(IS_CHROMEOS)

}  // namespace ui