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::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 MockCopresenceManager : public CopresenceManager {
72 explicit MockCopresenceManager(CopresenceDelegate* delegate)
73 : delegate_(delegate) {}
74 virtual ~MockCopresenceManager() {}
76 virtual void ExecuteReportRequest(
77 ReportRequest request,
78 const std::string& app_id,
79 const copresence::StatusCallback& status_callback) OVERRIDE {
82 status_callback.Run(copresence::SUCCESS);
85 CopresenceDelegate* delegate_;
87 ReportRequest request_;
91 class CopresenceApiUnittest : public ExtensionApiUnittest {
93 CopresenceApiUnittest() {}
94 virtual ~CopresenceApiUnittest() {}
96 virtual void SetUp() OVERRIDE {
97 ExtensionApiUnittest::SetUp();
99 CopresenceService* service =
100 CopresenceService::GetFactoryInstance()->Get(profile());
101 copresence_manager_ = new MockCopresenceManager(service);
102 service->set_manager_for_testing(
103 make_scoped_ptr<CopresenceManager>(copresence_manager_));
106 // Takes ownership of the operation_list.
107 bool ExecuteOperations(ListValue* operation_list) {
108 scoped_ptr<ListValue> args_list(new ListValue);
109 args_list->Append(operation_list);
111 scoped_refptr<UIThreadExtensionFunction> function =
112 new CopresenceExecuteFunction;
113 function->set_extension(extension());
114 function->set_browser_context(profile());
115 function->set_has_callback(true);
116 test_utils::RunFunction(
117 function.get(), args_list.Pass(), browser(), test_utils::NONE);
118 return function->GetResultList();
121 bool ExecuteOperation(scoped_ptr<Operation> operation) {
122 ListValue* operation_list = new ListValue;
123 operation_list->Append(operation->ToValue().release());
124 return ExecuteOperations(operation_list);
127 const ReportRequest& request_sent() const {
128 return copresence_manager_->request_;
131 const std::string& app_id_sent() const {
132 return copresence_manager_->app_id_;
135 void clear_app_id() {
136 copresence_manager_->app_id_ = "";
139 CopresenceDelegate* delegate() {
140 return copresence_manager_->delegate_;
144 MockCopresenceManager* copresence_manager_;
147 TEST_F(CopresenceApiUnittest, Publish) {
148 scoped_ptr<PublishOperation> publish(CreatePublish("pub"));
149 publish->strategies.reset(new Strategy);
150 publish->strategies->only_broadcast.reset(new bool(true)); // Default
152 scoped_ptr<Operation> operation(new Operation);
153 operation->publish = publish.Pass();
156 EXPECT_TRUE(ExecuteOperation(operation.Pass()));
157 EXPECT_EQ(extension()->id(), app_id_sent());
159 PublishedMessage message;
161 request_sent().manage_messages_request().message_to_publish(), &message));
162 EXPECT_EQ("pub", message.id());
163 EXPECT_EQ(1000, message.access_policy().ttl_millis());
164 EXPECT_EQ(copresence::NO_ACL_CHECK, message.access_policy().acl().acl_type());
165 EXPECT_EQ("joke", message.message().type().type());
166 EXPECT_EQ("Knock Knock!", message.message().payload());
167 EXPECT_EQ(BROADCAST_ONLY,
168 message.token_exchange_strategy().broadcast_scan_configuration());
169 EXPECT_EQ(AUDIO_CONFIGURATION_UNKNOWN,
170 message.token_exchange_strategy().audio_configuration());
173 TEST_F(CopresenceApiUnittest, Subscribe) {
174 scoped_ptr<SubscribeOperation> subscribe(CreateSubscribe("sub"));
175 subscribe->strategies.reset(new Strategy);
176 subscribe->strategies->only_broadcast.reset(new bool(true)); // Not default
177 subscribe->strategies->audible.reset(new bool(true)); // Not default
179 scoped_ptr<Operation> operation(new Operation);
180 operation->subscribe = subscribe.Pass();
183 EXPECT_TRUE(ExecuteOperation(operation.Pass()));
184 EXPECT_EQ(extension()->id(), app_id_sent());
186 Subscription subscription;
188 request_sent().manage_subscriptions_request().subscription(),
190 EXPECT_EQ("sub", subscription.id());
191 EXPECT_EQ(1000, subscription.ttl_millis());
192 EXPECT_EQ("joke", subscription.message_type().type());
193 copresence::BroadcastScanConfiguration broadcast_scan =
194 subscription.token_exchange_strategy().broadcast_scan_configuration();
195 EXPECT_EQ(BROADCAST_ONLY, broadcast_scan);
197 subscription.token_exchange_strategy().audio_configuration());
200 TEST_F(CopresenceApiUnittest, DefaultStrategies) {
201 scoped_ptr<Operation> publish_operation(new Operation);
202 publish_operation->publish.reset(CreatePublish("pub"));
204 scoped_ptr<Operation> subscribe_operation(new Operation);
205 subscribe_operation->subscribe.reset(CreateSubscribe("sub"));
207 ListValue* operation_list = new ListValue;
208 operation_list->Append(publish_operation->ToValue().release());
209 operation_list->Append(subscribe_operation->ToValue().release());
210 EXPECT_TRUE(ExecuteOperations(operation_list));
212 EXPECT_EQ(BROADCAST_ONLY,
213 request_sent().manage_messages_request().message_to_publish(0)
214 .token_exchange_strategy().broadcast_scan_configuration());
216 request_sent().manage_subscriptions_request().subscription(0)
217 .token_exchange_strategy().broadcast_scan_configuration());
220 TEST_F(CopresenceApiUnittest, UnPubSub) {
221 // First we need to create a publish and a subscribe to cancel.
222 scoped_ptr<Operation> publish_operation(new Operation);
223 scoped_ptr<Operation> subscribe_operation(new Operation);
224 publish_operation->publish.reset(CreatePublish("pub"));
225 subscribe_operation->subscribe.reset(CreateSubscribe("sub"));
226 ListValue* operation_list = new ListValue;
227 operation_list->Append(publish_operation->ToValue().release());
228 operation_list->Append(subscribe_operation->ToValue().release());
229 EXPECT_TRUE(ExecuteOperations(operation_list));
231 scoped_ptr<Operation> unpublish_operation(new Operation);
232 unpublish_operation->unpublish.reset(new UnpublishOperation);
233 unpublish_operation->unpublish->unpublish_id = "pub";
235 scoped_ptr<Operation> unsubscribe_operation(new Operation);
236 unsubscribe_operation->unsubscribe.reset(new UnsubscribeOperation);
237 unsubscribe_operation->unsubscribe->unsubscribe_id = "sub";
239 operation_list = new ListValue;
240 operation_list->Append(unpublish_operation->ToValue().release());
241 operation_list->Append(unsubscribe_operation->ToValue().release());
242 EXPECT_TRUE(ExecuteOperations(operation_list));
244 std::string unpublish_id;
246 request_sent().manage_messages_request().id_to_unpublish(),
248 EXPECT_EQ("pub", unpublish_id);
250 std::string unsubscribe_id;
252 request_sent().manage_subscriptions_request().id_to_unsubscribe(),
254 EXPECT_EQ("sub", unsubscribe_id);
257 TEST_F(CopresenceApiUnittest, BadId) {
258 scoped_ptr<Operation> unsubscribe_operation(new Operation);
259 unsubscribe_operation->unsubscribe.reset(new UnsubscribeOperation);
260 unsubscribe_operation->unsubscribe->unsubscribe_id = "invalid id";
262 EXPECT_FALSE(ExecuteOperation(unsubscribe_operation.Pass()));
265 TEST_F(CopresenceApiUnittest, MultipleOperations) {
266 scoped_ptr<Operation> multi_operation(new Operation);
267 multi_operation->publish.reset(CreatePublish("pub"));
268 multi_operation->subscribe.reset(CreateSubscribe("sub"));
270 EXPECT_FALSE(ExecuteOperation(multi_operation.Pass()));
273 } // namespace extensions