1 // Copyright 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.
5 #include "base/json/json_writer.h"
6 #include "base/values.h"
7 #include "chrome/browser/extensions/api/copresence/copresence_api.h"
8 #include "chrome/browser/extensions/extension_api_unittest.h"
9 #include "chrome/browser/extensions/extension_function_test_utils.h"
10 #include "components/copresence/proto/data.pb.h"
11 #include "components/copresence/proto/rpcs.pb.h"
12 #include "components/copresence/public/copresence_manager.h"
14 using base::ListValue
;
15 using copresence::AUDIO_CONFIGURATION_AUDIBLE
;
16 using copresence::AUDIO_CONFIGURATION_UNKNOWN
;
17 using copresence::BROADCAST_ONLY
;
18 using copresence::CopresenceDelegate
;
19 using copresence::CopresenceManager
;
20 using copresence::FAIL
;
21 using copresence::PublishedMessage
;
22 using copresence::ReportRequest
;
23 using copresence::SCAN_ONLY
;
24 using copresence::Subscription
;
25 using google::protobuf::RepeatedPtrField
;
27 namespace test_utils
= extension_function_test_utils
;
29 namespace extensions
{
31 using api::copresence::Message
;
32 using api::copresence::Operation
;
33 using api::copresence::PublishOperation
;
34 using api::copresence::Strategy
;
35 using api::copresence::SubscribeOperation
;
36 using api::copresence::UnpublishOperation
;
37 using api::copresence::UnsubscribeOperation
;
40 PublishOperation
* CreatePublish(const std::string
& id
) {
41 PublishOperation
* publish
= new PublishOperation
;
44 publish
->time_to_live_millis
.reset(new int(1000));
45 publish
->message
.type
= "joke";
46 std::string
payload("Knock Knock!");
47 publish
->message
.payload
.assign(payload
.begin(), payload
.end());
52 SubscribeOperation
* CreateSubscribe(const std::string
& id
) {
53 SubscribeOperation
* subscribe
= new SubscribeOperation
;
56 subscribe
->time_to_live_millis
.reset(new int(1000));
57 subscribe
->filter
.type
= "joke";
63 bool GetOnly(const RepeatedPtrField
<T
>& things
, T
* out
) {
64 if (things
.size() != 1)
71 class FakeCopresenceManager
: public CopresenceManager
{
73 explicit FakeCopresenceManager(CopresenceDelegate
* delegate
)
74 : delegate_(delegate
) {}
75 ~FakeCopresenceManager() override
{}
77 // CopresenceManager overrides.
78 copresence::CopresenceState
* state() override
{
82 void ExecuteReportRequest(
83 const ReportRequest
& request
,
84 const std::string
& app_id
,
85 const std::string
& /* auth_token */,
86 const copresence::StatusCallback
& status_callback
) override
{
89 status_callback
.Run(copresence::SUCCESS
);
92 CopresenceDelegate
* delegate_
;
94 ReportRequest request_
;
98 class CopresenceApiUnittest
: public ExtensionApiUnittest
{
100 CopresenceApiUnittest() {}
101 ~CopresenceApiUnittest() override
{}
103 void SetUp() override
{
104 ExtensionApiUnittest::SetUp();
106 CopresenceService
* service
=
107 CopresenceService::GetFactoryInstance()->Get(profile());
108 copresence_manager_
= new FakeCopresenceManager(service
);
109 service
->set_manager_for_testing(
110 make_scoped_ptr
<CopresenceManager
>(copresence_manager_
));
113 // Takes ownership of the operation_list.
114 bool ExecuteOperations(ListValue
* operation_list
) {
115 scoped_ptr
<ListValue
> args_list(new ListValue
);
116 args_list
->Append(operation_list
);
118 scoped_refptr
<UIThreadExtensionFunction
> function
=
119 new CopresenceExecuteFunction
;
120 function
->set_extension(extension());
121 function
->set_browser_context(profile());
122 function
->set_has_callback(true);
123 test_utils::RunFunction(
124 function
.get(), args_list
.Pass(), browser(), test_utils::NONE
);
125 return function
->GetResultList();
128 bool ExecuteOperation(scoped_ptr
<Operation
> operation
) {
129 ListValue
* operation_list
= new ListValue
;
130 operation_list
->Append(operation
->ToValue().release());
131 return ExecuteOperations(operation_list
);
134 const ReportRequest
& request_sent() const {
135 return copresence_manager_
->request_
;
138 const std::string
& app_id_sent() const {
139 return copresence_manager_
->app_id_
;
142 void clear_app_id() {
143 copresence_manager_
->app_id_
.clear();
146 CopresenceDelegate
* delegate() {
147 return copresence_manager_
->delegate_
;
151 FakeCopresenceManager
* copresence_manager_
;
154 TEST_F(CopresenceApiUnittest
, Publish
) {
155 scoped_ptr
<PublishOperation
> publish(CreatePublish("pub"));
156 publish
->strategies
.reset(new Strategy
);
157 publish
->strategies
->only_broadcast
.reset(new bool(true)); // Default
159 scoped_ptr
<Operation
> operation(new Operation
);
160 operation
->publish
= publish
.Pass();
163 EXPECT_TRUE(ExecuteOperation(operation
.Pass()));
164 EXPECT_EQ(extension()->id(), app_id_sent());
166 PublishedMessage message
;
168 request_sent().manage_messages_request().message_to_publish(), &message
));
169 EXPECT_EQ("pub", message
.id());
170 EXPECT_EQ(1000, message
.access_policy().ttl_millis());
171 EXPECT_EQ(copresence::NO_ACL_CHECK
, message
.access_policy().acl().acl_type());
172 EXPECT_EQ("joke", message
.message().type().type());
173 EXPECT_EQ("Knock Knock!", message
.message().payload());
174 EXPECT_EQ(BROADCAST_ONLY
,
175 message
.token_exchange_strategy().broadcast_scan_configuration());
176 EXPECT_EQ(AUDIO_CONFIGURATION_UNKNOWN
,
177 message
.token_exchange_strategy().audio_configuration());
180 TEST_F(CopresenceApiUnittest
, Subscribe
) {
181 scoped_ptr
<SubscribeOperation
> subscribe(CreateSubscribe("sub"));
182 subscribe
->strategies
.reset(new Strategy
);
183 subscribe
->strategies
->only_broadcast
.reset(new bool(true)); // Not default
184 subscribe
->strategies
->audible
.reset(new bool(true)); // Not default
186 scoped_ptr
<Operation
> operation(new Operation
);
187 operation
->subscribe
= subscribe
.Pass();
190 EXPECT_TRUE(ExecuteOperation(operation
.Pass()));
191 EXPECT_EQ(extension()->id(), app_id_sent());
193 Subscription subscription
;
195 request_sent().manage_subscriptions_request().subscription(),
197 EXPECT_EQ("sub", subscription
.id());
198 EXPECT_EQ(1000, subscription
.ttl_millis());
199 EXPECT_EQ("joke", subscription
.message_type().type());
200 copresence::BroadcastScanConfiguration broadcast_scan
=
201 subscription
.token_exchange_strategy().broadcast_scan_configuration();
202 EXPECT_EQ(BROADCAST_ONLY
, broadcast_scan
);
203 EXPECT_EQ(AUDIO_CONFIGURATION_AUDIBLE
,
204 subscription
.token_exchange_strategy().audio_configuration());
207 TEST_F(CopresenceApiUnittest
, DefaultStrategies
) {
208 scoped_ptr
<Operation
> publish_operation(new Operation
);
209 publish_operation
->publish
.reset(CreatePublish("pub"));
211 scoped_ptr
<Operation
> subscribe_operation(new Operation
);
212 subscribe_operation
->subscribe
.reset(CreateSubscribe("sub"));
214 ListValue
* operation_list
= new ListValue
;
215 operation_list
->Append(publish_operation
->ToValue().release());
216 operation_list
->Append(subscribe_operation
->ToValue().release());
217 EXPECT_TRUE(ExecuteOperations(operation_list
));
219 EXPECT_EQ(BROADCAST_ONLY
,
220 request_sent().manage_messages_request().message_to_publish(0)
221 .token_exchange_strategy().broadcast_scan_configuration());
223 request_sent().manage_subscriptions_request().subscription(0)
224 .token_exchange_strategy().broadcast_scan_configuration());
227 TEST_F(CopresenceApiUnittest
, LowPowerStrategy
) {
228 scoped_ptr
<Operation
> subscribe_operation(new Operation
);
229 subscribe_operation
->subscribe
.reset(CreateSubscribe("sub"));
230 subscribe_operation
->subscribe
->strategies
.reset(new Strategy
);
231 subscribe_operation
->subscribe
->strategies
->low_power
.reset(new bool(true));
233 ListValue
* operation_list
= new ListValue
;
234 operation_list
->Append(subscribe_operation
->ToValue().release());
235 EXPECT_TRUE(ExecuteOperations(operation_list
));
237 EXPECT_EQ(copresence::BROADCAST_SCAN_CONFIGURATION_UNKNOWN
,
238 request_sent().manage_subscriptions_request().subscription(0)
239 .token_exchange_strategy().broadcast_scan_configuration());
242 TEST_F(CopresenceApiUnittest
, UnPubSub
) {
243 // First we need to create a publish and a subscribe to cancel.
244 scoped_ptr
<Operation
> publish_operation(new Operation
);
245 scoped_ptr
<Operation
> subscribe_operation(new Operation
);
246 publish_operation
->publish
.reset(CreatePublish("pub"));
247 subscribe_operation
->subscribe
.reset(CreateSubscribe("sub"));
248 ListValue
* operation_list
= new ListValue
;
249 operation_list
->Append(publish_operation
->ToValue().release());
250 operation_list
->Append(subscribe_operation
->ToValue().release());
251 EXPECT_TRUE(ExecuteOperations(operation_list
));
253 scoped_ptr
<Operation
> unpublish_operation(new Operation
);
254 unpublish_operation
->unpublish
.reset(new UnpublishOperation
);
255 unpublish_operation
->unpublish
->unpublish_id
= "pub";
257 scoped_ptr
<Operation
> unsubscribe_operation(new Operation
);
258 unsubscribe_operation
->unsubscribe
.reset(new UnsubscribeOperation
);
259 unsubscribe_operation
->unsubscribe
->unsubscribe_id
= "sub";
261 operation_list
= new ListValue
;
262 operation_list
->Append(unpublish_operation
->ToValue().release());
263 operation_list
->Append(unsubscribe_operation
->ToValue().release());
264 EXPECT_TRUE(ExecuteOperations(operation_list
));
266 std::string unpublish_id
;
268 request_sent().manage_messages_request().id_to_unpublish(),
270 EXPECT_EQ("pub", unpublish_id
);
272 std::string unsubscribe_id
;
274 request_sent().manage_subscriptions_request().id_to_unsubscribe(),
276 EXPECT_EQ("sub", unsubscribe_id
);
279 TEST_F(CopresenceApiUnittest
, BadId
) {
280 scoped_ptr
<Operation
> unsubscribe_operation(new Operation
);
281 unsubscribe_operation
->unsubscribe
.reset(new UnsubscribeOperation
);
282 unsubscribe_operation
->unsubscribe
->unsubscribe_id
= "invalid id";
284 EXPECT_FALSE(ExecuteOperation(unsubscribe_operation
.Pass()));
287 TEST_F(CopresenceApiUnittest
, MultipleOperations
) {
288 scoped_ptr
<Operation
> multi_operation(new Operation
);
289 multi_operation
->publish
.reset(CreatePublish("pub"));
290 multi_operation
->subscribe
.reset(CreateSubscribe("sub"));
292 EXPECT_FALSE(ExecuteOperation(multi_operation
.Pass()));
295 } // namespace extensions
297 // TODO(ckehoe): add tests for auth tokens and api key functionality