1// Copyright (c) 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/at_exit.h"
6#include "base/bind.h"
7#include "mojo/common/common_type_converters.h"
8#include "mojo/services/public/interfaces/clipboard/clipboard.mojom.h"
9#include "mojo/shell/shell_test_helper.h"
10#include "testing/gtest/include/gtest/gtest.h"
11
12namespace {
13
14void CopyUint64AndEndRunloop(uint64_t* output,
15                             base::RunLoop* run_loop,
16                             uint64_t input) {
17  *output = input;
18  run_loop->Quit();
19}
20
21void CopyStringAndEndRunloop(std::string* output,
22                             bool* string_is_null,
23                             base::RunLoop* run_loop,
24                             const mojo::Array<uint8_t>& input) {
25  *string_is_null = input.is_null();
26  *output = input.is_null() ? "" : input.To<std::string>();
27  run_loop->Quit();
28}
29
30void CopyVectorStringAndEndRunloop(std::vector<std::string>* output,
31                                   base::RunLoop* run_loop,
32                                   const mojo::Array<mojo::String>& input) {
33  *output = input.To<std::vector<std::string> >();
34  run_loop->Quit();
35}
36
37const char* kUninitialized = "Uninitialized data";
38const char* kPlainTextData = "Some plain data";
39const char* kHtmlData = "<html>data</html>";
40
41}  // namespace
42
43namespace mojo {
44namespace service {
45
46class ClipboardStandaloneTest : public testing::Test {
47 public:
48  ClipboardStandaloneTest() {}
49  virtual ~ClipboardStandaloneTest() {}
50
51  virtual void SetUp() OVERRIDE {
52    test_helper_.Init();
53
54    test_helper_.application_manager()->ConnectToService(
55        GURL("mojo:mojo_clipboard"), &clipboard_);
56  }
57
58  uint64_t GetSequenceNumber() {
59    base::RunLoop run_loop;
60    uint64_t sequence_num = 999999;
61    clipboard_->GetSequenceNumber(
62        mojo::Clipboard::TYPE_COPY_PASTE,
63        base::Bind(&CopyUint64AndEndRunloop, &sequence_num, &run_loop));
64    run_loop.Run();
65    return sequence_num;
66  }
67
68  std::vector<std::string> GetAvailableFormatMimeTypes() {
69    base::RunLoop run_loop;
70    std::vector<std::string> types;
71    types.push_back(kUninitialized);
72    clipboard_->GetAvailableMimeTypes(
73        mojo::Clipboard::TYPE_COPY_PASTE,
74        base::Bind(&CopyVectorStringAndEndRunloop, &types, &run_loop));
75    run_loop.Run();
76    return types;
77  }
78
79  bool GetDataOfType(const std::string& mime_type, std::string* data) {
80    base::RunLoop run_loop;
81    bool is_null = false;
82    clipboard_->ReadMimeType(
83        mojo::Clipboard::TYPE_COPY_PASTE,
84        mime_type,
85        base::Bind(&CopyStringAndEndRunloop, data, &is_null, &run_loop));
86    run_loop.Run();
87    return !is_null;
88  }
89
90  void SetStringText(const std::string& data) {
91    Array<MimeTypePairPtr> mime_data;
92    MimeTypePairPtr text_data(MimeTypePair::New());
93    text_data->mime_type = mojo::Clipboard::MIME_TYPE_TEXT;
94    text_data->data = Array<uint8_t>::From(data).Pass();
95    mime_data.push_back(text_data.Pass());
96    clipboard_->WriteClipboardData(mojo::Clipboard::TYPE_COPY_PASTE,
97                                   mime_data.Pass());
98  }
99
100 protected:
101  base::ShadowingAtExitManager at_exit_;
102  shell::ShellTestHelper test_helper_;
103
104  ClipboardPtr clipboard_;
105
106  DISALLOW_COPY_AND_ASSIGN(ClipboardStandaloneTest);
107};
108
109TEST_F(ClipboardStandaloneTest, EmptyClipboardOK) {
110  EXPECT_EQ(0ul, GetSequenceNumber());
111  EXPECT_TRUE(GetAvailableFormatMimeTypes().empty());
112  std::string data;
113  EXPECT_FALSE(GetDataOfType(mojo::Clipboard::MIME_TYPE_TEXT, &data));
114}
115
116TEST_F(ClipboardStandaloneTest, CanReadBackText) {
117  std::string data;
118  EXPECT_FALSE(GetDataOfType(mojo::Clipboard::MIME_TYPE_TEXT, &data));
119  EXPECT_EQ(0ul, GetSequenceNumber());
120
121  SetStringText(kPlainTextData);
122  EXPECT_EQ(1ul, GetSequenceNumber());
123
124  EXPECT_TRUE(GetDataOfType(mojo::Clipboard::MIME_TYPE_TEXT, &data));
125  EXPECT_EQ(kPlainTextData, data);
126}
127
128TEST_F(ClipboardStandaloneTest, CanSetMultipleDataTypesAtOnce) {
129  Array<MimeTypePairPtr> mime_data;
130  MimeTypePairPtr text_data(MimeTypePair::New());
131  text_data->mime_type = mojo::Clipboard::MIME_TYPE_TEXT;
132  text_data->data = Array<uint8_t>::From(std::string(kPlainTextData)).Pass();
133  mime_data.push_back(text_data.Pass());
134
135  MimeTypePairPtr html_data(MimeTypePair::New());
136  html_data->mime_type = mojo::Clipboard::MIME_TYPE_HTML;
137  html_data->data = Array<uint8_t>::From(std::string(kHtmlData)).Pass();
138  mime_data.push_back(html_data.Pass());
139
140  clipboard_->WriteClipboardData(mojo::Clipboard::TYPE_COPY_PASTE,
141                                 mime_data.Pass());
142
143  EXPECT_EQ(1ul, GetSequenceNumber());
144
145  std::string data;
146  EXPECT_TRUE(GetDataOfType(mojo::Clipboard::MIME_TYPE_TEXT, &data));
147  EXPECT_EQ(kPlainTextData, data);
148  EXPECT_TRUE(GetDataOfType(mojo::Clipboard::MIME_TYPE_HTML, &data));
149  EXPECT_EQ(kHtmlData, data);
150}
151
152TEST_F(ClipboardStandaloneTest, CanClearClipboardWithNull) {
153  std::string data;
154  SetStringText(kPlainTextData);
155  EXPECT_EQ(1ul, GetSequenceNumber());
156
157  EXPECT_TRUE(GetDataOfType(mojo::Clipboard::MIME_TYPE_TEXT, &data));
158  EXPECT_EQ(kPlainTextData, data);
159
160  Array<MimeTypePairPtr> mime_data;
161  clipboard_->WriteClipboardData(mojo::Clipboard::TYPE_COPY_PASTE,
162                                 mime_data.Pass());
163
164  EXPECT_EQ(2ul, GetSequenceNumber());
165  EXPECT_FALSE(GetDataOfType(mojo::Clipboard::MIME_TYPE_TEXT, &data));
166}
167
168TEST_F(ClipboardStandaloneTest, CanClearClipboardWithZeroArray) {
169  std::string data;
170  SetStringText(kPlainTextData);
171  EXPECT_EQ(1ul, GetSequenceNumber());
172
173  EXPECT_TRUE(GetDataOfType(mojo::Clipboard::MIME_TYPE_TEXT, &data));
174  EXPECT_EQ(kPlainTextData, data);
175
176  Array<MimeTypePairPtr> mime_data(0);
177  clipboard_->WriteClipboardData(mojo::Clipboard::TYPE_COPY_PASTE,
178                                 mime_data.Pass());
179
180  EXPECT_EQ(2ul, GetSequenceNumber());
181  EXPECT_FALSE(GetDataOfType(mojo::Clipboard::MIME_TYPE_TEXT, &data));
182}
183
184}  // namespace service
185}  // namespace mojo
186