Shell / ShellClient -> ServiceProvider
[chromium-blink-merge.git] / mojo / services / view_manager / view_manager_connection_unittest.cc
blob5945f30f05e99b4415c4749a21c27ae07eae6b7b
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 <string>
6 #include <vector>
8 #include "base/bind.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "base/strings/stringprintf.h"
13 #include "mojo/common/common_type_converters.h"
14 #include "mojo/geometry/geometry_type_converters.h"
15 #include "mojo/public/cpp/application/connect.h"
16 #include "mojo/public/cpp/bindings/allocation_scope.h"
17 #include "mojo/public/cpp/environment/environment.h"
18 #include "mojo/services/public/cpp/view_manager/util.h"
19 #include "mojo/services/public/cpp/view_manager/view_manager_types.h"
20 #include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
21 #include "mojo/shell/shell_test_helper.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "ui/gfx/geometry/rect.h"
25 namespace mojo {
27 // TODO(sky): remove this when Darin is done with cleanup.
28 template <typename T>
29 class MOJO_COMMON_EXPORT TypeConverter<T, T> {
30 public:
31 static T ConvertFrom(T input, Buffer* buf) {
32 return input;
34 static T ConvertTo(T input) {
35 return input;
38 MOJO_ALLOW_IMPLICIT_TYPE_CONVERSION();
41 namespace view_manager {
42 namespace service {
44 namespace {
46 base::RunLoop* current_run_loop = NULL;
48 // Sets |current_run_loop| and runs it. It is expected that someone else quits
49 // the loop.
50 void DoRunLoop() {
51 DCHECK(!current_run_loop);
53 base::RunLoop run_loop;
54 current_run_loop = &run_loop;
55 current_run_loop->Run();
56 current_run_loop = NULL;
59 // Converts |id| into a string.
60 std::string NodeIdToString(TransportNodeId id) {
61 return (id == 0) ? "null" :
62 base::StringPrintf("%d,%d", HiWord(id), LoWord(id));
65 // Converts |rect| into a string.
66 std::string RectToString(const Rect& rect) {
67 return base::StringPrintf("%d,%d %dx%d",
68 rect.position().x(),
69 rect.position().y(),
70 rect.size().width(),
71 rect.size().height());
74 // Boolean callback. Sets |result_cache| to the value of |result| and quits
75 // the run loop.
76 void BooleanCallback(bool* result_cache, bool result) {
77 *result_cache = result;
78 current_run_loop->Quit();
81 struct TestNode {
82 std::string ToString() const {
83 return base::StringPrintf("node=%s parent=%s view=%s",
84 NodeIdToString(node_id).c_str(),
85 NodeIdToString(parent_id).c_str(),
86 NodeIdToString(view_id).c_str());
89 TransportNodeId parent_id;
90 TransportNodeId node_id;
91 TransportNodeId view_id;
94 void INodesToTestNodes(const mojo::Array<INode>& data,
95 std::vector<TestNode>* test_nodes) {
96 for (size_t i = 0; i < data.size(); ++i) {
97 TestNode node;
98 node.parent_id = data[i].parent_id();
99 node.node_id = data[i].node_id();
100 node.view_id = data[i].view_id();
101 test_nodes->push_back(node);
105 // Callback that results in a vector of INodes. The INodes are converted to
106 // TestNodes.
107 void INodesCallback(std::vector<TestNode>* test_nodes,
108 const mojo::Array<INode>& data) {
109 INodesToTestNodes(data, test_nodes);
110 current_run_loop->Quit();
113 // Creates an id used for transport from the specified parameters.
114 TransportNodeId CreateNodeId(TransportConnectionId connection_id,
115 TransportConnectionSpecificNodeId node_id) {
116 return (connection_id << 16) | node_id;
119 // Creates an id used for transport from the specified parameters.
120 TransportViewId CreateViewId(TransportConnectionId connection_id,
121 TransportConnectionSpecificViewId view_id) {
122 return (connection_id << 16) | view_id;
125 // Creates a node with the specified id. Returns true on success. Blocks until
126 // we get back result from server.
127 bool CreateNode(IViewManager* view_manager,
128 TransportConnectionId connection_id,
129 TransportConnectionSpecificNodeId node_id) {
130 bool result = false;
131 view_manager->CreateNode(CreateNodeId(connection_id, node_id),
132 base::Bind(&BooleanCallback, &result));
133 DoRunLoop();
134 return result;
137 // Deletes a view, blocking until done.
138 bool DeleteNode(IViewManager* view_manager, TransportNodeId node_id) {
139 bool result = false;
140 view_manager->DeleteNode(node_id, base::Bind(&BooleanCallback, &result));
141 DoRunLoop();
142 return result;
145 // Deletes a node, blocking until done.
146 bool DeleteView(IViewManager* view_manager, TransportViewId view_id) {
147 bool result = false;
148 view_manager->DeleteView(view_id, base::Bind(&BooleanCallback, &result));
149 DoRunLoop();
150 return result;
153 bool SetNodeBounds(IViewManager* view_manager,
154 TransportNodeId node_id,
155 const gfx::Rect& bounds) {
156 bool result = false;
157 view_manager->SetNodeBounds(node_id, bounds,
158 base::Bind(&BooleanCallback, &result));
159 DoRunLoop();
160 return result;
163 // Adds a node, blocking until done.
164 bool AddNode(IViewManager* view_manager,
165 TransportNodeId parent,
166 TransportNodeId child,
167 TransportChangeId server_change_id) {
168 bool result = false;
169 view_manager->AddNode(parent, child, server_change_id,
170 base::Bind(&BooleanCallback, &result));
171 DoRunLoop();
172 return result;
175 // Removes a node, blocking until done.
176 bool RemoveNodeFromParent(IViewManager* view_manager,
177 TransportNodeId node_id,
178 TransportChangeId server_change_id) {
179 bool result = false;
180 view_manager->RemoveNodeFromParent(
181 node_id, server_change_id, base::Bind(&BooleanCallback, &result));
182 DoRunLoop();
183 return result;
186 void GetNodeTree(IViewManager* view_manager,
187 TransportNodeId node_id,
188 std::vector<TestNode>* nodes) {
189 view_manager->GetNodeTree(node_id, base::Bind(&INodesCallback, nodes));
190 DoRunLoop();
193 // Creates a view with the specified id. Returns true on success. Blocks until
194 // we get back result from server.
195 bool CreateView(IViewManager* view_manager,
196 TransportConnectionId connection_id,
197 TransportConnectionSpecificViewId id) {
198 bool result = false;
199 view_manager->CreateView(CreateViewId(connection_id, id),
200 base::Bind(&BooleanCallback, &result));
201 DoRunLoop();
202 return result;
205 // Sets a view on the specified node. Returns true on success. Blocks until we
206 // get back result from server.
207 bool SetView(IViewManager* view_manager,
208 TransportNodeId node_id,
209 TransportViewId view_id) {
210 bool result = false;
211 view_manager->SetView(node_id, view_id,
212 base::Bind(&BooleanCallback, &result));
213 DoRunLoop();
214 return result;
217 bool SetRoots(IViewManager* view_manager,
218 TransportConnectionId connection_id,
219 const std::vector<uint32_t>& node_ids) {
220 bool result = false;
221 view_manager->SetRoots(connection_id,
222 Array<uint32_t>::From(node_ids),
223 base::Bind(&BooleanCallback, &result));
224 DoRunLoop();
225 return result;
228 } // namespace
230 typedef std::vector<std::string> Changes;
232 class ViewManagerClientImpl : public IViewManagerClient {
233 public:
234 ViewManagerClientImpl()
235 : id_(0),
236 next_server_change_id_(0),
237 quit_count_(0) {}
239 TransportConnectionId id() const { return id_; }
241 TransportChangeId next_server_change_id() const {
242 return next_server_change_id_;
244 const std::vector<TestNode>& initial_nodes() const {
245 return initial_nodes_;
247 const std::vector<TestNode>& hierarchy_changed_nodes() const {
248 return hierarchy_changed_nodes_;
251 Changes GetAndClearChanges() {
252 Changes changes;
253 changes.swap(changes_);
254 return changes;
257 void ClearId() {
258 id_ = 0;
261 void WaitForId() {
262 DCHECK_EQ(0, id_);
263 DoRunLoopUntilChangesCount(1);
266 void DoRunLoopUntilChangesCount(size_t count) {
267 if (changes_.size() >= count)
268 return;
269 quit_count_ = count - changes_.size();
270 DoRunLoop();
273 private:
274 // IViewManagerClient overrides:
275 virtual void OnViewManagerConnectionEstablished(
276 TransportConnectionId connection_id,
277 TransportChangeId next_server_change_id,
278 const mojo::Array<INode>& nodes) OVERRIDE {
279 id_ = connection_id;
280 next_server_change_id_ = next_server_change_id;
281 initial_nodes_.clear();
282 INodesToTestNodes(nodes, &initial_nodes_);
283 changes_.push_back("OnConnectionEstablished");
284 QuitIfNecessary();
286 virtual void OnServerChangeIdAdvanced(
287 uint32_t next_server_change_id) OVERRIDE {
288 changes_.push_back(
289 base::StringPrintf(
290 "ServerChangeIdAdvanced %d",
291 static_cast<int>(next_server_change_id)));
292 QuitIfNecessary();
294 virtual void OnNodeBoundsChanged(TransportNodeId node_id,
295 const Rect& old_bounds,
296 const Rect& new_bounds) OVERRIDE {
297 changes_.push_back(
298 base::StringPrintf(
299 "BoundsChanged node=%s old_bounds=%s new_bounds=%s",
300 NodeIdToString(node_id).c_str(),
301 RectToString(old_bounds).c_str(),
302 RectToString(new_bounds).c_str()));
303 QuitIfNecessary();
305 virtual void OnNodeHierarchyChanged(
306 TransportNodeId node,
307 TransportNodeId new_parent,
308 TransportNodeId old_parent,
309 TransportChangeId server_change_id,
310 const mojo::Array<INode>& nodes) OVERRIDE {
311 changes_.push_back(
312 base::StringPrintf(
313 "HierarchyChanged change_id=%d node=%s new_parent=%s old_parent=%s",
314 static_cast<int>(server_change_id),
315 NodeIdToString(node).c_str(),
316 NodeIdToString(new_parent).c_str(),
317 NodeIdToString(old_parent).c_str()));
318 hierarchy_changed_nodes_.clear();
319 INodesToTestNodes(nodes, &hierarchy_changed_nodes_);
320 QuitIfNecessary();
322 virtual void OnNodeDeleted(TransportNodeId node,
323 TransportChangeId server_change_id) OVERRIDE {
324 changes_.push_back(
325 base::StringPrintf(
326 "NodeDeleted change_id=%d node=%s",
327 static_cast<int>(server_change_id),
328 NodeIdToString(node).c_str()));
329 QuitIfNecessary();
331 virtual void OnViewDeleted(TransportViewId view) OVERRIDE {
332 changes_.push_back(
333 base::StringPrintf(
334 "ViewDeleted view=%s",
335 NodeIdToString(view).c_str()));
336 QuitIfNecessary();
338 virtual void OnNodeViewReplaced(TransportNodeId node,
339 TransportViewId new_view_id,
340 TransportViewId old_view_id) OVERRIDE {
341 changes_.push_back(
342 base::StringPrintf(
343 "ViewReplaced node=%s new_view=%s old_view=%s",
344 NodeIdToString(node).c_str(),
345 NodeIdToString(new_view_id).c_str(),
346 NodeIdToString(old_view_id).c_str()));
347 QuitIfNecessary();
350 void QuitIfNecessary() {
351 if (quit_count_ > 0 && --quit_count_ == 0)
352 current_run_loop->Quit();
355 TransportConnectionId id_;
356 TransportChangeId next_server_change_id_;
358 // Used to determine when/if to quit the run loop.
359 size_t quit_count_;
361 Changes changes_;
363 // Set of nodes sent when connection created.
364 std::vector<TestNode> initial_nodes_;
366 // Nodes sent from last OnNodeHierarchyChanged.
367 std::vector<TestNode> hierarchy_changed_nodes_;
369 DISALLOW_COPY_AND_ASSIGN(ViewManagerClientImpl);
372 class ViewManagerConnectionTest : public testing::Test {
373 public:
374 ViewManagerConnectionTest() {}
376 virtual void SetUp() OVERRIDE {
377 test_helper_.Init();
379 ConnectToService(test_helper_.service_provider(),
380 "mojo:mojo_view_manager",
381 &view_manager_);
382 view_manager_.set_client(&client_);
384 client_.WaitForId();
385 client_.GetAndClearChanges();
388 protected:
389 // Creates a second connection to the viewmanager.
390 void EstablishSecondConnection() {
391 ConnectToService(test_helper_.service_provider(),
392 "mojo:mojo_view_manager",
393 &view_manager2_);
394 view_manager2_.set_client(&client2_);
396 client2_.WaitForId();
397 client2_.GetAndClearChanges();
400 void EstablishSecondConnectionWithRoot(TransportNodeId root_id) {
401 EstablishSecondConnection();
402 client2_.ClearId();
404 AllocationScope scope;
405 std::vector<uint32_t> roots;
406 roots.push_back(root_id);
407 ASSERT_TRUE(SetRoots(view_manager_.get(), 2, roots));
408 client2_.DoRunLoopUntilChangesCount(1);
409 Changes changes(client2_.GetAndClearChanges());
410 ASSERT_EQ(1u, changes.size());
411 EXPECT_EQ("OnConnectionEstablished", changes[0]);
412 ASSERT_NE(0u, client2_.id());
413 const std::vector<TestNode>& nodes(client2_.initial_nodes());
414 ASSERT_EQ(1u, nodes.size());
415 EXPECT_EQ("node=1,1 parent=null view=null", nodes[0].ToString());
418 void DestroySecondConnection() {
419 view_manager2_.reset();
422 base::MessageLoop loop_;
423 shell::ShellTestHelper test_helper_;
425 ViewManagerClientImpl client_;
426 IViewManagerPtr view_manager_;
428 ViewManagerClientImpl client2_;
429 IViewManagerPtr view_manager2_;
431 DISALLOW_COPY_AND_ASSIGN(ViewManagerConnectionTest);
434 // Verifies client gets a valid id.
435 TEST_F(ViewManagerConnectionTest, ValidId) {
436 // All these tests assume 1 for the client id. The only real assertion here is
437 // the client id is not zero, but adding this as rest of code here assumes 1.
438 EXPECT_EQ(1, client_.id());
440 // Change ids start at 1 as well.
441 EXPECT_EQ(static_cast<TransportChangeId>(1), client_.next_server_change_id());
444 // Verifies two clients/connections get different ids.
445 TEST_F(ViewManagerConnectionTest, TwoClientsGetDifferentConnectionIds) {
446 EstablishSecondConnection();
447 EXPECT_NE(0, client2_.id());
448 EXPECT_NE(client_.id(), client2_.id());
451 // Verifies client gets a valid id.
452 TEST_F(ViewManagerConnectionTest, CreateNode) {
453 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
455 // Can't create a node with the same id.
456 ASSERT_FALSE(CreateNode(view_manager_.get(), 1, 1));
459 TEST_F(ViewManagerConnectionTest, CreateNodeFailsWithBogusConnectionId) {
460 EXPECT_FALSE(CreateNode(view_manager_.get(), 2, 1));
463 TEST_F(ViewManagerConnectionTest, CreateViewFailsWithBogusConnectionId) {
464 EXPECT_FALSE(CreateView(view_manager_.get(), 2, 1));
467 // Verifies hierarchy changes.
468 TEST_F(ViewManagerConnectionTest, AddRemoveNotify) {
469 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
470 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2));
472 EXPECT_TRUE(client_.GetAndClearChanges().empty());
474 EstablishSecondConnection();
475 EXPECT_TRUE(client2_.GetAndClearChanges().empty());
477 // Make 2 a child of 1.
479 AllocationScope scope;
480 ASSERT_TRUE(AddNode(view_manager_.get(),
481 CreateNodeId(client_.id(), 1),
482 CreateNodeId(client_.id(), 2),
483 1));
484 Changes changes(client_.GetAndClearChanges());
485 ASSERT_TRUE(changes.empty());
487 client2_.DoRunLoopUntilChangesCount(1);
488 changes = client2_.GetAndClearChanges();
489 ASSERT_EQ(1u, changes.size());
490 EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]);
493 // Remove 2 from its parent.
495 AllocationScope scope;
496 ASSERT_TRUE(RemoveNodeFromParent(view_manager_.get(),
497 CreateNodeId(client_.id(), 2),
498 2));
499 Changes changes(client_.GetAndClearChanges());
500 ASSERT_TRUE(changes.empty());
502 client2_.DoRunLoopUntilChangesCount(1);
503 changes = client2_.GetAndClearChanges();
504 ASSERT_EQ(1u, changes.size());
505 EXPECT_EQ("ServerChangeIdAdvanced 3", changes[0]);
509 // Verifies AddNode fails when node is already in position.
510 TEST_F(ViewManagerConnectionTest, AddNodeWithNoChange) {
511 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
512 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2));
514 EXPECT_TRUE(client_.GetAndClearChanges().empty());
516 EstablishSecondConnection();
517 EXPECT_TRUE(client2_.GetAndClearChanges().empty());
519 // Make 2 a child of 1.
521 AllocationScope scope;
522 ASSERT_TRUE(AddNode(view_manager_.get(),
523 CreateNodeId(client_.id(), 1),
524 CreateNodeId(client_.id(), 2),
525 1));
526 Changes changes(client_.GetAndClearChanges());
527 ASSERT_TRUE(changes.empty());
529 client2_.DoRunLoopUntilChangesCount(1);
530 changes = client2_.GetAndClearChanges();
531 ASSERT_EQ(1u, changes.size());
532 EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]);
535 // Try again, this should fail.
537 AllocationScope scope;
538 EXPECT_FALSE(AddNode(view_manager_.get(),
539 CreateNodeId(client_.id(), 1),
540 CreateNodeId(client_.id(), 2),
541 2));
542 Changes changes(client_.GetAndClearChanges());
543 EXPECT_TRUE(changes.empty());
547 // Verifies AddNode fails when node is already in position.
548 TEST_F(ViewManagerConnectionTest, AddAncestorFails) {
549 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
550 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2));
552 EXPECT_TRUE(client_.GetAndClearChanges().empty());
554 EstablishSecondConnection();
555 EXPECT_TRUE(client2_.GetAndClearChanges().empty());
557 // Make 2 a child of 1.
559 AllocationScope scope;
560 ASSERT_TRUE(AddNode(view_manager_.get(),
561 CreateNodeId(client_.id(), 1),
562 CreateNodeId(client_.id(), 2),
563 1));
564 Changes changes(client_.GetAndClearChanges());
565 ASSERT_TRUE(changes.empty());
567 client2_.DoRunLoopUntilChangesCount(1);
568 changes = client2_.GetAndClearChanges();
569 ASSERT_EQ(1u, changes.size());
570 EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]);
573 // Try to make 1 a child of 2, this should fail since 1 is an ancestor of 2.
575 AllocationScope scope;
576 EXPECT_FALSE(AddNode(view_manager_.get(),
577 CreateNodeId(client_.id(), 2),
578 CreateNodeId(client_.id(), 1),
579 2));
580 Changes changes(client_.GetAndClearChanges());
581 EXPECT_TRUE(changes.empty());
585 // Verifies adding with an invalid id fails.
586 TEST_F(ViewManagerConnectionTest, AddWithInvalidServerId) {
587 // Create two nodes.
588 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
589 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2));
591 // Make 2 a child of 1. Supply an invalid change id, which should fail.
593 AllocationScope scope;
594 ASSERT_FALSE(AddNode(view_manager_.get(),
595 CreateNodeId(client_.id(), 1),
596 CreateNodeId(client_.id(), 2),
597 0));
598 Changes changes(client_.GetAndClearChanges());
599 EXPECT_TRUE(changes.empty());
603 // Verifies adding to root sends right notifications.
604 TEST_F(ViewManagerConnectionTest, AddToRoot) {
605 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 21));
606 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 3));
607 EXPECT_TRUE(client_.GetAndClearChanges().empty());
609 EstablishSecondConnection();
610 EXPECT_TRUE(client2_.GetAndClearChanges().empty());
612 // Make 3 a child of 21.
614 AllocationScope scope;
615 ASSERT_TRUE(AddNode(view_manager_.get(),
616 CreateNodeId(client_.id(), 21),
617 CreateNodeId(client_.id(), 3),
618 1));
619 Changes changes(client_.GetAndClearChanges());
620 ASSERT_TRUE(changes.empty());
622 client2_.DoRunLoopUntilChangesCount(1);
623 changes = client2_.GetAndClearChanges();
624 ASSERT_EQ(1u, changes.size());
625 EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]);
628 // Make 21 a child of the root.
630 AllocationScope scope;
631 ASSERT_TRUE(AddNode(view_manager_.get(),
632 CreateNodeId(0, 1),
633 CreateNodeId(client_.id(), 21),
634 2));
635 Changes changes(client_.GetAndClearChanges());
636 ASSERT_TRUE(changes.empty());
638 client2_.DoRunLoopUntilChangesCount(1);
639 changes = client2_.GetAndClearChanges();
640 ASSERT_EQ(1u, changes.size());
641 EXPECT_EQ(
642 "HierarchyChanged change_id=2 node=1,21 new_parent=0,1 old_parent=null",
643 changes[0]);
647 // Verifies adding to root sends right notifications.
648 TEST_F(ViewManagerConnectionTest, NodeHierarchyChangedNodes) {
649 // Create nodes 1 and 11 with 1 parented to the root and 11 a child of 1.
650 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
651 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 11));
653 // Make 11 a child of 1.
655 AllocationScope scope;
656 ASSERT_TRUE(AddNode(view_manager_.get(),
657 CreateNodeId(client_.id(), 1),
658 CreateNodeId(client_.id(), 11),
659 1));
660 ASSERT_TRUE(client_.GetAndClearChanges().empty());
663 EstablishSecondConnection();
665 // Make 1 a child of the root.
667 AllocationScope scope;
668 ASSERT_TRUE(AddNode(view_manager_.get(),
669 CreateNodeId(0, 1),
670 CreateNodeId(client_.id(), 1),
671 2));
672 ASSERT_TRUE(client_.GetAndClearChanges().empty());
674 // Client 2 should get a hierarchy change that includes the new nodes as it
675 // has not yet seen them.
676 client2_.DoRunLoopUntilChangesCount(1);
677 Changes changes(client2_.GetAndClearChanges());
678 ASSERT_EQ(1u, changes.size());
679 EXPECT_EQ(
680 "HierarchyChanged change_id=2 node=1,1 new_parent=0,1 old_parent=null",
681 changes[0]);
682 const std::vector<TestNode>& nodes(client2_.hierarchy_changed_nodes());
683 ASSERT_EQ(2u, nodes.size());
684 EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[0].ToString());
685 EXPECT_EQ("node=1,11 parent=1,1 view=null", nodes[1].ToString());
688 // Remove 1 from the root.
690 AllocationScope scope;
691 ASSERT_TRUE(RemoveNodeFromParent(view_manager_.get(),
692 CreateNodeId(client_.id(), 1),
693 3));
694 ASSERT_TRUE(client_.GetAndClearChanges().empty());
696 client2_.DoRunLoopUntilChangesCount(1);
697 Changes changes(client2_.GetAndClearChanges());
698 ASSERT_EQ(1u, changes.size());
699 EXPECT_EQ(
700 "HierarchyChanged change_id=3 node=1,1 new_parent=null old_parent=0,1",
701 changes[0]);
704 // Create another node, 111, parent it to 11.
705 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 111));
707 AllocationScope scope;
708 ASSERT_TRUE(AddNode(view_manager_.get(),
709 CreateNodeId(client_.id(), 11),
710 CreateNodeId(client_.id(), 111),
711 4));
712 ASSERT_TRUE(client_.GetAndClearChanges().empty());
714 client2_.DoRunLoopUntilChangesCount(1);
715 Changes changes(client2_.GetAndClearChanges());
716 ASSERT_EQ(1u, changes.size());
717 // Even though 11 isn't attached to the root client 2 is still notified of
718 // the change because it was told about 11.
719 EXPECT_EQ(
720 "HierarchyChanged change_id=4 node=1,111 new_parent=1,11 "
721 "old_parent=null", changes[0]);
722 const std::vector<TestNode>& nodes(client2_.hierarchy_changed_nodes());
723 ASSERT_EQ(1u, nodes.size());
724 EXPECT_EQ("node=1,111 parent=1,11 view=null", nodes[0].ToString());
727 // Reattach 1 to the root.
729 ASSERT_TRUE(AddNode(view_manager_.get(),
730 CreateNodeId(0, 1),
731 CreateNodeId(client_.id(), 1),
732 5));
733 ASSERT_TRUE(client_.GetAndClearChanges().empty());
735 client2_.DoRunLoopUntilChangesCount(1);
736 Changes changes = client2_.GetAndClearChanges();
737 ASSERT_EQ(1u, changes.size());
738 EXPECT_EQ(
739 "HierarchyChanged change_id=5 node=1,1 new_parent=0,1 old_parent=null",
740 changes[0]);
741 ASSERT_TRUE(client2_.hierarchy_changed_nodes().empty());
745 TEST_F(ViewManagerConnectionTest, NodeHierarchyChangedAddingKnownToUnknown) {
746 // Create the following structure: root -> 1 -> 11 and 2->21 (2 has no
747 // parent).
748 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
749 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 11));
750 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2));
751 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 21));
753 // Set up the hierarchy.
755 AllocationScope scope;
756 ASSERT_TRUE(AddNode(view_manager_.get(),
757 CreateNodeId(0, 1),
758 CreateNodeId(client_.id(), 1),
759 1));
760 ASSERT_TRUE(AddNode(view_manager_.get(),
761 CreateNodeId(client_.id(), 1),
762 CreateNodeId(client_.id(), 11),
763 2));
764 ASSERT_TRUE(AddNode(view_manager_.get(),
765 CreateNodeId(client_.id(), 2),
766 CreateNodeId(client_.id(), 21),
767 3));
770 EstablishSecondConnection();
772 // Remove 11.
774 AllocationScope scope;
775 ASSERT_TRUE(RemoveNodeFromParent(view_manager_.get(),
776 CreateNodeId(client_.id(), 11),
777 4));
778 ASSERT_TRUE(client_.GetAndClearChanges().empty());
780 client2_.DoRunLoopUntilChangesCount(1);
781 Changes changes(client2_.GetAndClearChanges());
782 ASSERT_EQ(1u, changes.size());
783 EXPECT_EQ(
784 "HierarchyChanged change_id=4 node=1,11 new_parent=null old_parent=1,1",
785 changes[0]);
786 EXPECT_TRUE(client2_.hierarchy_changed_nodes().empty());
789 // Add 11 to 21. As client2 knows about 11 it should receive the new
790 // hierarchy.
792 AllocationScope scope;
793 ASSERT_TRUE(AddNode(view_manager_.get(),
794 CreateNodeId(client_.id(), 21),
795 CreateNodeId(client_.id(), 11),
796 5));
797 ASSERT_TRUE(client_.GetAndClearChanges().empty());
799 client2_.DoRunLoopUntilChangesCount(1);
800 Changes changes(client2_.GetAndClearChanges());
801 ASSERT_EQ(1u, changes.size());
802 EXPECT_EQ(
803 "HierarchyChanged change_id=5 node=1,11 new_parent=1,21 "
804 "old_parent=null", changes[0]);
805 const std::vector<TestNode>& nodes(client2_.hierarchy_changed_nodes());
806 ASSERT_EQ(2u, nodes.size());
807 EXPECT_EQ("node=1,2 parent=null view=null", nodes[0].ToString());
808 EXPECT_EQ("node=1,21 parent=1,2 view=null", nodes[1].ToString());
812 // Verifies connection on told descendants of the root when connecting.
813 TEST_F(ViewManagerConnectionTest, GetInitialNodesOnInit) {
814 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 21));
815 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 3));
816 EXPECT_TRUE(client_.GetAndClearChanges().empty());
818 // Make 3 a child of 21.
820 AllocationScope scope;
821 ASSERT_TRUE(AddNode(view_manager_.get(),
822 CreateNodeId(client_.id(), 21),
823 CreateNodeId(client_.id(), 3),
824 1));
825 ASSERT_TRUE(client_.GetAndClearChanges().empty());
828 // Make 21 a child of the root.
830 AllocationScope scope;
831 ASSERT_TRUE(AddNode(view_manager_.get(),
832 CreateNodeId(0, 1),
833 CreateNodeId(client_.id(), 21),
834 2));
835 ASSERT_TRUE(client_.GetAndClearChanges().empty());
838 EstablishSecondConnection();
839 // Should get notification of children of the root.
840 const std::vector<TestNode>& nodes(client2_.initial_nodes());
841 ASSERT_EQ(3u, nodes.size());
842 EXPECT_EQ("node=0,1 parent=null view=null", nodes[0].ToString());
843 EXPECT_EQ("node=1,21 parent=0,1 view=null", nodes[1].ToString());
844 EXPECT_EQ("node=1,3 parent=1,21 view=null", nodes[2].ToString());
847 // Verifies DeleteNode works.
848 TEST_F(ViewManagerConnectionTest, DeleteNode) {
849 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
850 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2));
851 EXPECT_TRUE(client_.GetAndClearChanges().empty());
853 EstablishSecondConnection();
854 EXPECT_TRUE(client2_.GetAndClearChanges().empty());
856 // Make 2 a child of 1.
858 AllocationScope scope;
859 ASSERT_TRUE(AddNode(view_manager_.get(),
860 CreateNodeId(client_.id(), 1),
861 CreateNodeId(client_.id(), 2),
862 1));
863 Changes changes(client_.GetAndClearChanges());
864 ASSERT_TRUE(changes.empty());
866 client2_.DoRunLoopUntilChangesCount(1);
867 changes = client2_.GetAndClearChanges();
868 ASSERT_EQ(1u, changes.size());
869 EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]);
872 // Add 1 to the root
874 AllocationScope scope;
875 ASSERT_TRUE(AddNode(view_manager_.get(),
876 CreateNodeId(0, 1),
877 CreateNodeId(client_.id(), 1),
878 2));
879 Changes changes(client_.GetAndClearChanges());
880 ASSERT_TRUE(changes.empty());
882 client2_.DoRunLoopUntilChangesCount(1);
883 changes = client2_.GetAndClearChanges();
884 ASSERT_EQ(1u, changes.size());
885 EXPECT_EQ(
886 "HierarchyChanged change_id=2 node=1,1 new_parent=0,1 old_parent=null",
887 changes[0]);
890 // Delete 1.
892 AllocationScope scope;
893 ASSERT_TRUE(DeleteNode(view_manager_.get(), CreateNodeId(client_.id(), 1)));
894 Changes changes(client_.GetAndClearChanges());
895 ASSERT_TRUE(changes.empty());
897 client2_.DoRunLoopUntilChangesCount(1);
898 changes = client2_.GetAndClearChanges();
899 ASSERT_EQ(1u, changes.size());
900 EXPECT_EQ("NodeDeleted change_id=3 node=1,1", changes[0]);
904 // Verifies DeleteNode isn't allowed from a separate connection.
905 TEST_F(ViewManagerConnectionTest, DeleteNodeFromAnotherConnectionDisallowed) {
906 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
907 EstablishSecondConnection();
908 EXPECT_FALSE(DeleteNode(view_manager2_.get(), CreateNodeId(client_.id(), 1)));
911 // Verifies DeleteView isn't allowed from a separate connection.
912 TEST_F(ViewManagerConnectionTest, DeleteViewFromAnotherConnectionDisallowed) {
913 ASSERT_TRUE(CreateView(view_manager_.get(), 1, 1));
914 EstablishSecondConnection();
915 EXPECT_FALSE(DeleteView(view_manager2_.get(), CreateViewId(client_.id(), 1)));
918 // Verifies if a node was deleted and then reused that other clients are
919 // properly notified.
920 TEST_F(ViewManagerConnectionTest, ReusedDeletedId) {
921 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
922 EXPECT_TRUE(client_.GetAndClearChanges().empty());
924 EstablishSecondConnection();
926 // Make 1 a child of the root.
928 AllocationScope scope;
929 ASSERT_TRUE(AddNode(view_manager_.get(),
930 CreateNodeId(0, 1),
931 CreateNodeId(client_.id(), 1),
932 1));
933 EXPECT_TRUE(client_.GetAndClearChanges().empty());
935 client2_.DoRunLoopUntilChangesCount(1);
936 Changes changes = client2_.GetAndClearChanges();
937 EXPECT_EQ(
938 "HierarchyChanged change_id=1 node=1,1 new_parent=0,1 old_parent=null",
939 changes[0]);
940 const std::vector<TestNode>& nodes(client2_.hierarchy_changed_nodes());
941 ASSERT_EQ(1u, nodes.size());
942 EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[0].ToString());
945 // Delete 1.
947 AllocationScope scope;
948 ASSERT_TRUE(DeleteNode(view_manager_.get(), CreateNodeId(client_.id(), 1)));
949 EXPECT_TRUE(client_.GetAndClearChanges().empty());
951 client2_.DoRunLoopUntilChangesCount(1);
952 Changes changes = client2_.GetAndClearChanges();
953 ASSERT_EQ(1u, changes.size());
954 EXPECT_EQ("NodeDeleted change_id=2 node=1,1", changes[0]);
957 // Create 1 again, and add it back to the root. Should get the same
958 // notification.
959 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
961 AllocationScope scope;
962 ASSERT_TRUE(AddNode(view_manager_.get(),
963 CreateNodeId(0, 1),
964 CreateNodeId(client_.id(), 1),
965 3));
966 EXPECT_TRUE(client_.GetAndClearChanges().empty());
968 client2_.DoRunLoopUntilChangesCount(1);
969 Changes changes = client2_.GetAndClearChanges();
970 EXPECT_EQ(
971 "HierarchyChanged change_id=3 node=1,1 new_parent=0,1 old_parent=null",
972 changes[0]);
973 const std::vector<TestNode>& nodes(client2_.hierarchy_changed_nodes());
974 ASSERT_EQ(1u, nodes.size());
975 EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[0].ToString());
979 // Assertions around setting a view.
980 TEST_F(ViewManagerConnectionTest, SetView) {
981 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
982 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2));
983 ASSERT_TRUE(CreateView(view_manager_.get(), 1, 11));
984 ASSERT_TRUE(AddNode(view_manager_.get(), 1, CreateNodeId(1, 1), 1));
985 ASSERT_TRUE(AddNode(view_manager_.get(), 1, CreateNodeId(1, 2), 2));
986 EXPECT_TRUE(client_.GetAndClearChanges().empty());
988 EstablishSecondConnection();
989 EXPECT_TRUE(client2_.GetAndClearChanges().empty());
991 // Set view 11 on node 1.
993 ASSERT_TRUE(SetView(view_manager_.get(),
994 CreateNodeId(client_.id(), 1),
995 CreateViewId(client_.id(), 11)));
996 Changes changes(client_.GetAndClearChanges());
997 ASSERT_TRUE(changes.empty());
999 client2_.DoRunLoopUntilChangesCount(1);
1000 changes = client2_.GetAndClearChanges();
1001 ASSERT_EQ(1u, changes.size());
1002 EXPECT_EQ(
1003 "ViewReplaced node=1,1 new_view=1,11 old_view=null",
1004 changes[0]);
1007 // Set view 11 on node 2.
1009 ASSERT_TRUE(SetView(view_manager_.get(),
1010 CreateNodeId(client_.id(), 2),
1011 CreateViewId(client_.id(), 11)));
1012 Changes changes(client_.GetAndClearChanges());
1013 ASSERT_TRUE(changes.empty());
1015 client2_.DoRunLoopUntilChangesCount(2);
1016 changes = client2_.GetAndClearChanges();
1017 ASSERT_EQ(2u, changes.size());
1018 EXPECT_EQ("ViewReplaced node=1,1 new_view=null old_view=1,11",
1019 changes[0]);
1020 EXPECT_EQ("ViewReplaced node=1,2 new_view=1,11 old_view=null",
1021 changes[1]);
1025 // Verifies deleting a node with a view sends correct notifications.
1026 TEST_F(ViewManagerConnectionTest, DeleteNodeWithView) {
1027 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
1028 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2));
1029 ASSERT_TRUE(CreateView(view_manager_.get(), 1, 11));
1030 EXPECT_TRUE(client_.GetAndClearChanges().empty());
1032 // Set view 11 on node 1.
1033 ASSERT_TRUE(SetView(view_manager_.get(),
1034 CreateNodeId(client_.id(), 1),
1035 CreateViewId(client_.id(), 11)));
1036 client_.GetAndClearChanges();
1038 EstablishSecondConnection();
1039 EXPECT_TRUE(client2_.GetAndClearChanges().empty());
1041 // Delete node 1. The second connection should not see this because the node
1042 // was not known to it.
1044 ASSERT_TRUE(DeleteNode(view_manager_.get(), CreateNodeId(client_.id(), 1)));
1045 Changes changes(client_.GetAndClearChanges());
1046 ASSERT_TRUE(changes.empty());
1048 client2_.DoRunLoopUntilChangesCount(1);
1049 changes = client2_.GetAndClearChanges();
1050 ASSERT_EQ(1u, changes.size());
1051 EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]);
1054 // Parent 2 to the root.
1055 ASSERT_TRUE(AddNode(view_manager_.get(),
1056 CreateNodeId(0, 1),
1057 CreateNodeId(client_.id(), 2),
1058 2));
1059 client2_.DoRunLoopUntilChangesCount(1);
1060 client2_.GetAndClearChanges();
1062 // Set view 11 on node 2.
1064 ASSERT_TRUE(SetView(view_manager_.get(),
1065 CreateNodeId(client_.id(), 2),
1066 CreateViewId(client_.id(), 11)));
1067 Changes changes(client_.GetAndClearChanges());
1068 ASSERT_TRUE(changes.empty());
1070 client2_.DoRunLoopUntilChangesCount(1);
1071 changes = client2_.GetAndClearChanges();
1072 ASSERT_EQ(1u, changes.size());
1073 EXPECT_EQ("ViewReplaced node=1,2 new_view=1,11 old_view=null", changes[0]);
1076 // Delete node.
1078 ASSERT_TRUE(DeleteNode(view_manager_.get(), CreateNodeId(client_.id(), 2)));
1079 Changes changes(client_.GetAndClearChanges());
1080 ASSERT_TRUE(changes.empty());
1082 client2_.DoRunLoopUntilChangesCount(2);
1083 changes = client2_.GetAndClearChanges();
1084 ASSERT_EQ(2u, changes.size());
1085 EXPECT_EQ("ViewReplaced node=1,2 new_view=null old_view=1,11", changes[0]);
1086 EXPECT_EQ("NodeDeleted change_id=3 node=1,2", changes[1]);
1090 // Sets view from one connection on another.
1091 TEST_F(ViewManagerConnectionTest, SetViewFromSecondConnection) {
1092 EstablishSecondConnection();
1094 // Create two nodes in first connection.
1095 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
1096 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2));
1098 EXPECT_TRUE(client_.GetAndClearChanges().empty());
1099 EXPECT_TRUE(client2_.GetAndClearChanges().empty());
1101 // Create a view in the second connection.
1102 ASSERT_TRUE(CreateView(view_manager2_.get(), 2, 51));
1104 // Attach view to node 1 in the first connectoin.
1106 ASSERT_TRUE(SetView(view_manager2_.get(),
1107 CreateNodeId(client_.id(), 1),
1108 CreateViewId(client2_.id(), 51)));
1109 client_.DoRunLoopUntilChangesCount(1);
1110 Changes changes(client_.GetAndClearChanges());
1111 ASSERT_EQ(1u, changes.size());
1112 EXPECT_EQ("ViewReplaced node=1,1 new_view=2,51 old_view=null", changes[0]);
1115 // Shutdown the second connection and verify view is removed.
1117 DestroySecondConnection();
1118 client_.DoRunLoopUntilChangesCount(2);
1120 Changes changes(client_.GetAndClearChanges());
1121 ASSERT_EQ(2u, changes.size());
1122 EXPECT_EQ("ViewReplaced node=1,1 new_view=null old_view=2,51", changes[0]);
1123 EXPECT_EQ("ViewDeleted view=2,51", changes[1]);
1127 // Assertions for GetNodeTree.
1128 TEST_F(ViewManagerConnectionTest, GetNodeTree) {
1129 EstablishSecondConnection();
1131 // Create two nodes in first connection, 1 and 11 (11 is a child of 1).
1132 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
1133 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 11));
1134 ASSERT_TRUE(AddNode(view_manager_.get(),
1135 CreateNodeId(0, 1),
1136 CreateNodeId(client_.id(), 1),
1137 1));
1138 ASSERT_TRUE(AddNode(view_manager_.get(),
1139 CreateNodeId(client_.id(), 1),
1140 CreateNodeId(client_.id(), 11),
1141 2));
1143 // Create two nodes in second connection, 2 and 3, both children of the root.
1144 ASSERT_TRUE(CreateNode(view_manager2_.get(), 2, 2));
1145 ASSERT_TRUE(CreateNode(view_manager2_.get(), 2, 3));
1146 ASSERT_TRUE(AddNode(view_manager2_.get(),
1147 CreateNodeId(0, 1),
1148 CreateNodeId(client2_.id(), 2),
1149 3));
1150 ASSERT_TRUE(AddNode(view_manager2_.get(),
1151 CreateNodeId(0, 1),
1152 CreateNodeId(client2_.id(), 3),
1153 4));
1155 // Attach view to node 11 in the first connection.
1156 ASSERT_TRUE(CreateView(view_manager_.get(), 1, 51));
1157 ASSERT_TRUE(SetView(view_manager_.get(),
1158 CreateNodeId(client_.id(), 11),
1159 CreateViewId(client_.id(), 51)));
1161 // Verifies GetNodeTree() on the root.
1163 AllocationScope scope;
1164 std::vector<TestNode> nodes;
1165 GetNodeTree(view_manager2_.get(), CreateNodeId(0, 1), &nodes);
1166 ASSERT_EQ(5u, nodes.size());
1167 EXPECT_EQ("node=0,1 parent=null view=null", nodes[0].ToString());
1168 EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[1].ToString());
1169 EXPECT_EQ("node=1,11 parent=1,1 view=1,51", nodes[2].ToString());
1170 EXPECT_EQ("node=2,2 parent=0,1 view=null", nodes[3].ToString());
1171 EXPECT_EQ("node=2,3 parent=0,1 view=null", nodes[4].ToString());
1174 // Verifies GetNodeTree() on the node 1,1.
1176 AllocationScope scope;
1177 std::vector<TestNode> nodes;
1178 GetNodeTree(view_manager2_.get(), CreateNodeId(1, 1), &nodes);
1179 ASSERT_EQ(2u, nodes.size());
1180 EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[0].ToString());
1181 EXPECT_EQ("node=1,11 parent=1,1 view=1,51", nodes[1].ToString());
1185 TEST_F(ViewManagerConnectionTest, SetNodeBounds) {
1186 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
1187 ASSERT_TRUE(AddNode(view_manager_.get(),
1188 CreateNodeId(0, 1),
1189 CreateNodeId(1, 1),
1190 1));
1191 EstablishSecondConnection();
1193 AllocationScope scope;
1194 ASSERT_TRUE(SetNodeBounds(view_manager_.get(),
1195 CreateNodeId(1, 1),
1196 gfx::Rect(0, 0, 100, 100)));
1198 client2_.DoRunLoopUntilChangesCount(1);
1199 Changes changes(client2_.GetAndClearChanges());
1200 ASSERT_EQ(1u, changes.size());
1201 EXPECT_EQ("BoundsChanged node=1,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100",
1202 changes[0]);
1204 // Should not be possible to change the bounds of a node created by another
1205 // connection.
1206 ASSERT_FALSE(SetNodeBounds(view_manager2_.get(),
1207 CreateNodeId(1, 1),
1208 gfx::Rect(0, 0, 0, 0)));
1211 // Various assertions around SetRoots.
1212 TEST_F(ViewManagerConnectionTest, SetRoots) {
1213 // Create 1, 2, and 3 in the first connection.
1214 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
1215 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2));
1216 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 3));
1218 // Parent 1 to the root.
1219 ASSERT_TRUE(AddNode(view_manager_.get(),
1220 CreateNodeId(0, 1),
1221 CreateNodeId(client_.id(), 1),
1222 1));
1224 // Establish the second connection and give it the roots 1 and 3.
1225 EstablishSecondConnection();
1226 client2_.ClearId();
1228 AllocationScope scope;
1229 std::vector<uint32_t> roots;
1230 roots.push_back(CreateNodeId(1, 1));
1231 roots.push_back(CreateNodeId(1, 3));
1232 ASSERT_TRUE(SetRoots(view_manager_.get(), 2, roots));
1233 client2_.DoRunLoopUntilChangesCount(1);
1234 Changes changes(client2_.GetAndClearChanges());
1235 ASSERT_EQ(1u, changes.size());
1236 EXPECT_EQ("OnConnectionEstablished", changes[0]);
1237 ASSERT_NE(0u, client2_.id());
1238 const std::vector<TestNode>& nodes(client2_.initial_nodes());
1239 ASSERT_EQ(2u, nodes.size());
1240 EXPECT_EQ("node=1,1 parent=null view=null", nodes[0].ToString());
1241 EXPECT_EQ("node=1,3 parent=null view=null", nodes[1].ToString());
1244 // Create 4 and add it to the root, connection 2 should only get id advanced.
1246 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 4));
1247 ASSERT_TRUE(AddNode(view_manager_.get(),
1248 CreateNodeId(0, 1),
1249 CreateNodeId(client_.id(), 4),
1250 2));
1251 client2_.DoRunLoopUntilChangesCount(1);
1252 Changes changes(client2_.GetAndClearChanges());
1253 ASSERT_EQ(1u, changes.size());
1254 EXPECT_EQ("ServerChangeIdAdvanced 3", changes[0]);
1257 // Move 4 under 3, this should expose 4 to the client.
1259 ASSERT_TRUE(AddNode(view_manager_.get(),
1260 CreateNodeId(1, 3),
1261 CreateNodeId(1, 4),
1262 3));
1263 client2_.DoRunLoopUntilChangesCount(1);
1264 Changes changes(client2_.GetAndClearChanges());
1265 ASSERT_EQ(1u, changes.size());
1266 EXPECT_EQ(
1267 "HierarchyChanged change_id=3 node=1,4 new_parent=1,3 "
1268 "old_parent=null", changes[0]);
1269 const std::vector<TestNode>& nodes(client2_.hierarchy_changed_nodes());
1270 ASSERT_EQ(1u, nodes.size());
1271 EXPECT_EQ("node=1,4 parent=1,3 view=null", nodes[0].ToString());
1274 // Move 4 under 2, since 2 isn't a root client should get a delete.
1276 ASSERT_TRUE(AddNode(view_manager_.get(),
1277 CreateNodeId(1, 2),
1278 CreateNodeId(1, 4),
1279 4));
1280 client2_.DoRunLoopUntilChangesCount(1);
1281 Changes changes(client2_.GetAndClearChanges());
1282 ASSERT_EQ(1u, changes.size());
1283 EXPECT_EQ("NodeDeleted change_id=4 node=1,4", changes[0]);
1286 // Delete 4, client shouldn't receive a delete since it should no longer know
1287 // about 4.
1289 ASSERT_TRUE(DeleteNode(view_manager_.get(), CreateNodeId(client_.id(), 4)));
1290 ASSERT_TRUE(client_.GetAndClearChanges().empty());
1292 client2_.DoRunLoopUntilChangesCount(1);
1293 Changes changes(client2_.GetAndClearChanges());
1294 ASSERT_EQ(1u, changes.size());
1295 EXPECT_EQ("ServerChangeIdAdvanced 6", changes[0]);
1299 // Verify AddNode fails when trying to manipulate nodes in other roots.
1300 TEST_F(ViewManagerConnectionTest, CantMoveNodesFromOtherRoot) {
1301 // Create 1 and 2 in the first connection.
1302 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
1303 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2));
1305 // Establish the second connection and give it the root 1.
1306 ASSERT_NO_FATAL_FAILURE(
1307 EstablishSecondConnectionWithRoot(CreateNodeId(1, 1)));
1309 // Try to move 2 to be a child of 1 from connection 2. This should fail as 2
1310 // should not be able to access 1.
1311 ASSERT_FALSE(AddNode(view_manager2_.get(),
1312 CreateNodeId(1, 1),
1313 CreateNodeId(1, 2),
1314 1));
1316 // Try to reparent 1 to the root. A connection is not allowed to reparent its
1317 // roots.
1318 ASSERT_FALSE(AddNode(view_manager2_.get(),
1319 CreateNodeId(0, 1),
1320 CreateNodeId(1, 1),
1321 1));
1325 // Verify RemoveNodeFromParent fails for nodes that are descendants of the
1326 // roots.
1327 TEST_F(ViewManagerConnectionTest, CantRemoveNodesInOtherRoots) {
1328 // Create 1 and 2 in the first connection and parent both to the root.
1329 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
1330 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2));
1332 ASSERT_TRUE(AddNode(view_manager_.get(),
1333 CreateNodeId(0, 1),
1334 CreateNodeId(client_.id(), 1),
1335 1));
1336 ASSERT_TRUE(AddNode(view_manager_.get(),
1337 CreateNodeId(0, 1),
1338 CreateNodeId(client_.id(), 2),
1339 2));
1341 // Establish the second connection and give it the root 1.
1342 ASSERT_NO_FATAL_FAILURE(
1343 EstablishSecondConnectionWithRoot(CreateNodeId(1, 1)));
1345 // Connection 2 should not be able to remove node 2 or 1 from its parent.
1346 ASSERT_FALSE(RemoveNodeFromParent(view_manager2_.get(),
1347 CreateNodeId(1, 2),
1348 3));
1349 ASSERT_FALSE(RemoveNodeFromParent(view_manager2_.get(),
1350 CreateNodeId(1, 1),
1351 3));
1353 // Create nodes 10 and 11 in 2.
1354 ASSERT_TRUE(CreateNode(view_manager2_.get(), 2, 10));
1355 ASSERT_TRUE(CreateNode(view_manager2_.get(), 2, 11));
1357 // Parent 11 to 10.
1358 ASSERT_TRUE(AddNode(view_manager2_.get(),
1359 CreateNodeId(client2_.id(), 10),
1360 CreateNodeId(client2_.id(), 11),
1361 3));
1362 // Remove 11 from 10.
1363 ASSERT_TRUE(RemoveNodeFromParent(view_manager2_.get(),
1364 CreateNodeId(2, 11),
1365 4));
1367 // Verify nothing was actually removed.
1369 AllocationScope scope;
1370 std::vector<TestNode> nodes;
1371 GetNodeTree(view_manager_.get(), CreateNodeId(0, 1), &nodes);
1372 ASSERT_EQ(3u, nodes.size());
1373 EXPECT_EQ("node=0,1 parent=null view=null", nodes[0].ToString());
1374 EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[1].ToString());
1375 EXPECT_EQ("node=1,2 parent=0,1 view=null", nodes[2].ToString());
1379 // Verify SetView fails for nodes that are not descendants of the roots.
1380 TEST_F(ViewManagerConnectionTest, CantRemoveSetViewInOtherRoots) {
1381 // Create 1 and 2 in the first connection and parent both to the root.
1382 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
1383 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2));
1385 ASSERT_TRUE(AddNode(view_manager_.get(),
1386 CreateNodeId(0, 1),
1387 CreateNodeId(client_.id(), 1),
1388 1));
1389 ASSERT_TRUE(AddNode(view_manager_.get(),
1390 CreateNodeId(0, 1),
1391 CreateNodeId(client_.id(), 2),
1392 2));
1394 // Establish the second connection and give it the root 1.
1395 ASSERT_NO_FATAL_FAILURE(
1396 EstablishSecondConnectionWithRoot(CreateNodeId(1, 1)));
1398 // Create a view in the second connection.
1399 ASSERT_TRUE(CreateView(view_manager2_.get(), 2, 51));
1401 // Connection 2 should be able to set the view on node 1 (it's root), but not
1402 // on 2.
1403 ASSERT_TRUE(SetView(view_manager2_.get(),
1404 CreateNodeId(client_.id(), 1),
1405 CreateViewId(client2_.id(), 51)));
1406 ASSERT_FALSE(SetView(view_manager2_.get(),
1407 CreateNodeId(client_.id(), 2),
1408 CreateViewId(client2_.id(), 51)));
1411 // Verify GetNodeTree fails for nodes that are not descendants of the roots.
1412 TEST_F(ViewManagerConnectionTest, CantGetNodeTreeOfOtherRoots) {
1413 // Create 1 and 2 in the first connection and parent both to the root.
1414 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1));
1415 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2));
1417 ASSERT_TRUE(AddNode(view_manager_.get(),
1418 CreateNodeId(0, 1),
1419 CreateNodeId(client_.id(), 1),
1420 1));
1421 ASSERT_TRUE(AddNode(view_manager_.get(),
1422 CreateNodeId(0, 1),
1423 CreateNodeId(client_.id(), 2),
1424 2));
1426 // Establish the second connection and give it the root 1.
1427 ASSERT_NO_FATAL_FAILURE(
1428 EstablishSecondConnectionWithRoot(CreateNodeId(1, 1)));
1430 AllocationScope scope;
1431 std::vector<TestNode> nodes;
1433 // Should get nothing for the root.
1434 GetNodeTree(view_manager2_.get(), CreateNodeId(0, 1), &nodes);
1435 ASSERT_TRUE(nodes.empty());
1437 // Should get nothing for node 2.
1438 GetNodeTree(view_manager2_.get(), CreateNodeId(1, 2), &nodes);
1439 ASSERT_TRUE(nodes.empty());
1441 // Should get node 1 if asked for.
1442 GetNodeTree(view_manager2_.get(), CreateNodeId(1, 1), &nodes);
1443 ASSERT_EQ(1u, nodes.size());
1444 EXPECT_EQ("node=1,1 parent=null view=null", nodes[0].ToString());
1447 // TODO(sky): add coverage of test that destroys connections and ensures other
1448 // connections get deletion notification (or advanced server id).
1450 } // namespace service
1451 } // namespace view_manager
1452 } // namespace mojo