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 publish
->message
.payload
= "Knock Knock!";
51 SubscribeOperation
* CreateSubscribe(const std::string
& id
) {
52 SubscribeOperation
* subscribe
= new SubscribeOperation
;
55 subscribe
->time_to_live_millis
.reset(new int(1000));
56 subscribe
->filter
.type
= "joke";
62 bool GetOnly(const RepeatedPtrField
<T
>& things
, T
* out
) {
63 if (things
.size() != 1)
70 class FakeCopresenceManager
: public CopresenceManager
{
72 explicit FakeCopresenceManager(CopresenceDelegate
* delegate
)
73 : delegate_(delegate
) {}
74 ~FakeCopresenceManager() override
{}
76 // CopresenceManager overrides.
77 copresence::CopresenceState
* state() override
{
81 void ExecuteReportRequest(
82 const ReportRequest
& request
,
83 const std::string
& app_id
,
84 const std::string
& /* auth_token */,
85 const copresence::StatusCallback
& status_callback
) override
{
88 status_callback
.Run(copresence::SUCCESS
);
91 CopresenceDelegate
* delegate_
;
93 ReportRequest request_
;
97 class CopresenceApiUnittest
: public ExtensionApiUnittest
{
99 CopresenceApiUnittest() {}
100 ~CopresenceApiUnittest() override
{}
102 void SetUp() override
{
103 ExtensionApiUnittest::SetUp();
105 CopresenceService
* service
=
106 CopresenceService::GetFactoryInstance()->Get(profile());
107 copresence_manager_
= new FakeCopresenceManager(service
);
108 service
->set_manager_for_testing(
109 make_scoped_ptr
<CopresenceManager
>(copresence_manager_
));
112 // Takes ownership of the operation_list.
113 bool ExecuteOperations(ListValue
* operation_list
) {
114 scoped_ptr
<ListValue
> args_list(new ListValue
);
115 args_list
->Append(operation_list
);
117 scoped_refptr
<UIThreadExtensionFunction
> function
=
118 new CopresenceExecuteFunction
;
119 function
->set_extension(extension());
120 function
->set_browser_context(profile());
121 function
->set_has_callback(true);
122 test_utils::RunFunction(
123 function
.get(), args_list
.Pass(), browser(), test_utils::NONE
);
124 return function
->GetResultList();
127 bool ExecuteOperation(scoped_ptr
<Operation
> operation
) {
128 ListValue
* operation_list
= new ListValue
;
129 operation_list
->Append(operation
->ToValue().release());
130 return ExecuteOperations(operation_list
);
133 const ReportRequest
& request_sent() const {
134 return copresence_manager_
->request_
;
137 const std::string
& app_id_sent() const {
138 return copresence_manager_
->app_id_
;
141 void clear_app_id() {
142 copresence_manager_
->app_id_
.clear();
145 CopresenceDelegate
* delegate() {
146 return copresence_manager_
->delegate_
;
150 FakeCopresenceManager
* copresence_manager_
;
153 TEST_F(CopresenceApiUnittest
, Publish
) {
154 scoped_ptr
<PublishOperation
> publish(CreatePublish("pub"));
155 publish
->strategies
.reset(new Strategy
);
156 publish
->strategies
->only_broadcast
.reset(new bool(true)); // Default
158 scoped_ptr
<Operation
> operation(new Operation
);
159 operation
->publish
= publish
.Pass();
162 EXPECT_TRUE(ExecuteOperation(operation
.Pass()));
163 EXPECT_EQ(extension()->id(), app_id_sent());
165 PublishedMessage message
;
167 request_sent().manage_messages_request().message_to_publish(), &message
));
168 EXPECT_EQ("pub", message
.id());
169 EXPECT_EQ(1000, message
.access_policy().ttl_millis());
170 EXPECT_EQ(copresence::NO_ACL_CHECK
, message
.access_policy().acl().acl_type());
171 EXPECT_EQ("joke", message
.message().type().type());
172 EXPECT_EQ("Knock Knock!", message
.message().payload());
173 EXPECT_EQ(BROADCAST_ONLY
,
174 message
.token_exchange_strategy().broadcast_scan_configuration());
175 EXPECT_EQ(AUDIO_CONFIGURATION_UNKNOWN
,
176 message
.token_exchange_strategy().audio_configuration());
179 TEST_F(CopresenceApiUnittest
, Subscribe
) {
180 scoped_ptr
<SubscribeOperation
> subscribe(CreateSubscribe("sub"));
181 subscribe
->strategies
.reset(new Strategy
);
182 subscribe
->strategies
->only_broadcast
.reset(new bool(true)); // Not default
183 subscribe
->strategies
->audible
.reset(new bool(true)); // Not default
185 scoped_ptr
<Operation
> operation(new Operation
);
186 operation
->subscribe
= subscribe
.Pass();
189 EXPECT_TRUE(ExecuteOperation(operation
.Pass()));
190 EXPECT_EQ(extension()->id(), app_id_sent());
192 Subscription subscription
;
194 request_sent().manage_subscriptions_request().subscription(),
196 EXPECT_EQ("sub", subscription
.id());
197 EXPECT_EQ(1000, subscription
.ttl_millis());
198 EXPECT_EQ("joke", subscription
.message_type().type());
199 copresence::BroadcastScanConfiguration broadcast_scan
=
200 subscription
.token_exchange_strategy().broadcast_scan_configuration();
201 EXPECT_EQ(BROADCAST_ONLY
, broadcast_scan
);
202 EXPECT_EQ(AUDIO_CONFIGURATION_AUDIBLE
,
203 subscription
.token_exchange_strategy().audio_configuration());
206 TEST_F(CopresenceApiUnittest
, DefaultStrategies
) {
207 scoped_ptr
<Operation
> publish_operation(new Operation
);
208 publish_operation
->publish
.reset(CreatePublish("pub"));
210 scoped_ptr
<Operation
> subscribe_operation(new Operation
);
211 subscribe_operation
->subscribe
.reset(CreateSubscribe("sub"));
213 ListValue
* operation_list
= new ListValue
;
214 operation_list
->Append(publish_operation
->ToValue().release());
215 operation_list
->Append(subscribe_operation
->ToValue().release());
216 EXPECT_TRUE(ExecuteOperations(operation_list
));
218 EXPECT_EQ(BROADCAST_ONLY
,
219 request_sent().manage_messages_request().message_to_publish(0)
220 .token_exchange_strategy().broadcast_scan_configuration());
222 request_sent().manage_subscriptions_request().subscription(0)
223 .token_exchange_strategy().broadcast_scan_configuration());
226 TEST_F(CopresenceApiUnittest
, LowPowerStrategy
) {
227 scoped_ptr
<Operation
> subscribe_operation(new Operation
);
228 subscribe_operation
->subscribe
.reset(CreateSubscribe("sub"));
229 subscribe_operation
->subscribe
->strategies
.reset(new Strategy
);
230 subscribe_operation
->subscribe
->strategies
->low_power
.reset(new bool(true));
232 ListValue
* operation_list
= new ListValue
;
233 operation_list
->Append(subscribe_operation
->ToValue().release());
234 EXPECT_TRUE(ExecuteOperations(operation_list
));
236 EXPECT_EQ(copresence::BROADCAST_SCAN_CONFIGURATION_UNKNOWN
,
237 request_sent().manage_subscriptions_request().subscription(0)
238 .token_exchange_strategy().broadcast_scan_configuration());
241 TEST_F(CopresenceApiUnittest
, UnPubSub
) {
242 // First we need to create a publish and a subscribe to cancel.
243 scoped_ptr
<Operation
> publish_operation(new Operation
);
244 scoped_ptr
<Operation
> subscribe_operation(new Operation
);
245 publish_operation
->publish
.reset(CreatePublish("pub"));
246 subscribe_operation
->subscribe
.reset(CreateSubscribe("sub"));
247 ListValue
* operation_list
= new ListValue
;
248 operation_list
->Append(publish_operation
->ToValue().release());
249 operation_list
->Append(subscribe_operation
->ToValue().release());
250 EXPECT_TRUE(ExecuteOperations(operation_list
));
252 scoped_ptr
<Operation
> unpublish_operation(new Operation
);
253 unpublish_operation
->unpublish
.reset(new UnpublishOperation
);
254 unpublish_operation
->unpublish
->unpublish_id
= "pub";
256 scoped_ptr
<Operation
> unsubscribe_operation(new Operation
);
257 unsubscribe_operation
->unsubscribe
.reset(new UnsubscribeOperation
);
258 unsubscribe_operation
->unsubscribe
->unsubscribe_id
= "sub";
260 operation_list
= new ListValue
;
261 operation_list
->Append(unpublish_operation
->ToValue().release());
262 operation_list
->Append(unsubscribe_operation
->ToValue().release());
263 EXPECT_TRUE(ExecuteOperations(operation_list
));
265 std::string unpublish_id
;
267 request_sent().manage_messages_request().id_to_unpublish(),
269 EXPECT_EQ("pub", unpublish_id
);
271 std::string unsubscribe_id
;
273 request_sent().manage_subscriptions_request().id_to_unsubscribe(),
275 EXPECT_EQ("sub", unsubscribe_id
);
278 TEST_F(CopresenceApiUnittest
, BadId
) {
279 scoped_ptr
<Operation
> unsubscribe_operation(new Operation
);
280 unsubscribe_operation
->unsubscribe
.reset(new UnsubscribeOperation
);
281 unsubscribe_operation
->unsubscribe
->unsubscribe_id
= "invalid id";
283 EXPECT_FALSE(ExecuteOperation(unsubscribe_operation
.Pass()));
286 TEST_F(CopresenceApiUnittest
, MultipleOperations
) {
287 scoped_ptr
<Operation
> multi_operation(new Operation
);
288 multi_operation
->publish
.reset(CreatePublish("pub"));
289 multi_operation
->subscribe
.reset(CreateSubscribe("sub"));
291 EXPECT_FALSE(ExecuteOperation(multi_operation
.Pass()));
294 } // namespace extensions
296 // TODO(ckehoe): add tests for auth tokens and api key functionality