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.
4
5#include <string>
6#include <vector>
7
8#include "base/at_exit.h"
9#include "base/auto_reset.h"
10#include "base/bind.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/memory/scoped_vector.h"
13#include "base/message_loop/message_loop.h"
14#include "base/run_loop.h"
15#include "base/strings/stringprintf.h"
16#include "mojo/common/common_type_converters.h"
17#include "mojo/public/cpp/application/application.h"
18#include "mojo/public/cpp/application/connect.h"
19#include "mojo/public/cpp/bindings/lib/router.h"
20#include "mojo/service_manager/service_manager.h"
21#include "mojo/services/public/cpp/geometry/geometry_type_converters.h"
22#include "mojo/services/public/cpp/view_manager/types.h"
23#include "mojo/services/public/cpp/view_manager/util.h"
24#include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
25#include "mojo/services/view_manager/ids.h"
26#include "mojo/services/view_manager/test_change_tracker.h"
27#include "mojo/shell/shell_test_helper.h"
28#include "testing/gtest/include/gtest/gtest.h"
29#include "ui/gfx/geometry/rect.h"
30
31namespace mojo {
32namespace view_manager {
33namespace service {
34
35namespace {
36
37const char kTestServiceURL[] = "mojo:test_url";
38
39// ViewManagerProxy is a proxy to an ViewManagerService. It handles invoking
40// ViewManagerService functions on the right thread in a synchronous manner
41// (each ViewManagerService cover function blocks until the response from the
42// ViewManagerService is returned). In addition it tracks the set of
43// ViewManagerClient messages received by way of a vector of Changes. Use
44// DoRunLoopUntilChangesCount() to wait for a certain number of messages to be
45// received.
46class ViewManagerProxy : public TestChangeTracker::Delegate {
47 public:
48  explicit ViewManagerProxy(TestChangeTracker* tracker)
49      : tracker_(tracker),
50        view_manager_(NULL),
51        quit_count_(0),
52        router_(NULL) {
53    SetInstance(this);
54  }
55
56  virtual ~ViewManagerProxy() {}
57
58  // Runs a message loop until the single instance has been created.
59  static ViewManagerProxy* WaitForInstance() {
60    if (!instance_)
61      RunMainLoop();
62    ViewManagerProxy* instance = instance_;
63    instance_ = NULL;
64    return instance;
65  }
66
67  ViewManagerService* view_manager() { return view_manager_; }
68
69  // Runs the main loop until |count| changes have been received.
70  std::vector<Change> DoRunLoopUntilChangesCount(size_t count) {
71    DCHECK_EQ(0u, quit_count_);
72    if (tracker_->changes()->size() >= count) {
73      CopyChangesFromTracker();
74      return changes_;
75    }
76    quit_count_ = count - tracker_->changes()->size();
77    // Run the current message loop. When |count| Changes have been received,
78    // we'll quit.
79    RunMainLoop();
80    return changes_;
81  }
82
83  const std::vector<Change>& changes() const { return changes_; }
84
85  // Destroys the connection, blocking until done.
86  void Destroy() {
87    router_->CloseMessagePipe();
88  }
89
90  // The following functions are cover methods for ViewManagerService. They
91  // block until the result is received.
92  bool CreateNode(Id node_id) {
93    changes_.clear();
94    bool result = false;
95    view_manager_->CreateNode(node_id,
96                              base::Bind(&ViewManagerProxy::GotResult,
97                                         base::Unretained(this), &result));
98    RunMainLoop();
99    return result;
100  }
101  bool AddNode(Id parent, Id child, Id server_change_id) {
102    changes_.clear();
103    bool result = false;
104    view_manager_->AddNode(parent, child, server_change_id,
105                           base::Bind(&ViewManagerProxy::GotResult,
106                                      base::Unretained(this), &result));
107    RunMainLoop();
108    return result;
109  }
110  bool RemoveNodeFromParent(Id node_id, Id server_change_id) {
111    changes_.clear();
112    bool result = false;
113    view_manager_->RemoveNodeFromParent(node_id, server_change_id,
114        base::Bind(&ViewManagerProxy::GotResult,
115                   base::Unretained(this), &result));
116    RunMainLoop();
117    return result;
118  }
119  bool ReorderNode(Id node_id,
120                   Id relative_node_id,
121                   OrderDirection direction,
122                   Id server_change_id) {
123    changes_.clear();
124    bool result = false;
125    view_manager_->ReorderNode(node_id, relative_node_id, direction,
126                               server_change_id,
127                               base::Bind(&ViewManagerProxy::GotResult,
128                                          base::Unretained(this), &result));
129    RunMainLoop();
130    return result;
131  }
132  bool SetView(Id node_id, Id view_id) {
133    changes_.clear();
134    bool result = false;
135    view_manager_->SetView(node_id, view_id,
136                           base::Bind(&ViewManagerProxy::GotResult,
137                                      base::Unretained(this), &result));
138    RunMainLoop();
139    return result;
140  }
141  bool CreateView(Id view_id) {
142    changes_.clear();
143    bool result = false;
144    view_manager_->CreateView(view_id,
145                              base::Bind(&ViewManagerProxy::GotResult,
146                                         base::Unretained(this), &result));
147    RunMainLoop();
148    return result;
149  }
150  void GetNodeTree(Id node_id, std::vector<TestNode>* nodes) {
151    changes_.clear();
152    view_manager_->GetNodeTree(node_id,
153                               base::Bind(&ViewManagerProxy::GotNodeTree,
154                                          base::Unretained(this), nodes));
155    RunMainLoop();
156  }
157  bool Embed(const std::vector<Id>& nodes) {
158    changes_.clear();
159    base::AutoReset<bool> auto_reset(&in_embed_, true);
160    bool result = false;
161    view_manager_->Embed(kTestServiceURL, Array<Id>::From(nodes),
162                         base::Bind(&ViewManagerProxy::GotResult,
163                                    base::Unretained(this), &result));
164    RunMainLoop();
165    return result;
166  }
167  bool DeleteNode(Id node_id, Id server_change_id) {
168    changes_.clear();
169    bool result = false;
170    view_manager_->DeleteNode(node_id,
171                              server_change_id,
172                              base::Bind(&ViewManagerProxy::GotResult,
173                                         base::Unretained(this), &result));
174    RunMainLoop();
175    return result;
176  }
177  bool DeleteView(Id view_id) {
178    changes_.clear();
179    bool result = false;
180    view_manager_->DeleteView(view_id,
181                              base::Bind(&ViewManagerProxy::GotResult,
182                                         base::Unretained(this), &result));
183    RunMainLoop();
184    return result;
185  }
186  bool SetNodeBounds(Id node_id, const gfx::Rect& bounds) {
187    changes_.clear();
188    bool result = false;
189    view_manager_->SetNodeBounds(node_id, Rect::From(bounds),
190                                 base::Bind(&ViewManagerProxy::GotResult,
191                                            base::Unretained(this), &result));
192    RunMainLoop();
193    return result;
194  }
195
196 private:
197  friend class TestViewManagerClientConnection;
198
199  void set_router(mojo::internal::Router* router) { router_ = router; }
200
201  void set_view_manager(ViewManagerService* view_manager) {
202    view_manager_ = view_manager;
203  }
204
205  static void RunMainLoop() {
206    DCHECK(!main_run_loop_);
207    main_run_loop_ = new base::RunLoop;
208    main_run_loop_->Run();
209    delete main_run_loop_;
210    main_run_loop_ = NULL;
211  }
212
213  void QuitCountReached() {
214    CopyChangesFromTracker();
215    main_run_loop_->Quit();
216  }
217
218  void CopyChangesFromTracker() {
219    std::vector<Change> changes;
220    tracker_->changes()->swap(changes);
221    changes_.swap(changes);
222  }
223
224  static void SetInstance(ViewManagerProxy* instance) {
225    DCHECK(!instance_);
226    instance_ = instance;
227    // Embed() runs its own run loop that is quit when the result is
228    // received. Embed() also results in a new instance. If we quit here while
229    // waiting for a Embed() we would prematurely return before we got the
230    // result from Embed().
231    if (!in_embed_ && main_run_loop_)
232      main_run_loop_->Quit();
233  }
234
235  // Callbacks from the various ViewManagerService functions.
236  void GotResult(bool* result_cache, bool result) {
237    *result_cache = result;
238    DCHECK(main_run_loop_);
239    main_run_loop_->Quit();
240  }
241
242  void GotNodeTree(std::vector<TestNode>* nodes, Array<NodeDataPtr> results) {
243    NodeDatasToTestNodes(results, nodes);
244    DCHECK(main_run_loop_);
245    main_run_loop_->Quit();
246  }
247
248  // TestChangeTracker::Delegate:
249  virtual void OnChangeAdded() OVERRIDE {
250    if (quit_count_ > 0 && --quit_count_ == 0)
251      QuitCountReached();
252  }
253
254  static ViewManagerProxy* instance_;
255  static base::RunLoop* main_run_loop_;
256  static bool in_embed_;
257
258  TestChangeTracker* tracker_;
259
260  // MessageLoop of the test.
261  base::MessageLoop* main_loop_;
262
263  ViewManagerService* view_manager_;
264
265  // Number of changes we're waiting on until we quit the current loop.
266  size_t quit_count_;
267
268  std::vector<Change> changes_;
269
270  mojo::internal::Router* router_;
271
272  DISALLOW_COPY_AND_ASSIGN(ViewManagerProxy);
273};
274
275// static
276ViewManagerProxy* ViewManagerProxy::instance_ = NULL;
277
278// static
279base::RunLoop* ViewManagerProxy::main_run_loop_ = NULL;
280
281// static
282bool ViewManagerProxy::in_embed_ = false;
283
284class TestViewManagerClientConnection
285    : public InterfaceImpl<ViewManagerClient> {
286 public:
287  TestViewManagerClientConnection() : connection_(&tracker_) {
288    tracker_.set_delegate(&connection_);
289  }
290
291  // InterfaceImp:
292  virtual void OnConnectionEstablished() OVERRIDE {
293    connection_.set_router(internal_state()->router());
294    connection_.set_view_manager(client());
295  }
296
297  // ViewMangerClient:
298  virtual void OnViewManagerConnectionEstablished(
299      ConnectionSpecificId connection_id,
300      const String& creator_url,
301      Id next_server_change_id,
302      Array<NodeDataPtr> nodes) OVERRIDE {
303    tracker_.OnViewManagerConnectionEstablished(
304        connection_id, creator_url, next_server_change_id, nodes.Pass());
305  }
306  virtual void OnRootsAdded(Array<NodeDataPtr> nodes) OVERRIDE {
307    tracker_.OnRootsAdded(nodes.Pass());
308  }
309  virtual void OnServerChangeIdAdvanced(
310      Id next_server_change_id) OVERRIDE {
311    tracker_.OnServerChangeIdAdvanced(next_server_change_id);
312  }
313  virtual void OnNodeBoundsChanged(Id node_id,
314                                   RectPtr old_bounds,
315                                   RectPtr new_bounds) OVERRIDE {
316    tracker_.OnNodeBoundsChanged(node_id, old_bounds.Pass(), new_bounds.Pass());
317  }
318  virtual void OnNodeHierarchyChanged(Id node,
319                                      Id new_parent,
320                                      Id old_parent,
321                                      Id server_change_id,
322                                      Array<NodeDataPtr> nodes) OVERRIDE {
323    tracker_.OnNodeHierarchyChanged(node, new_parent, old_parent,
324                                    server_change_id, nodes.Pass());
325  }
326  virtual void OnNodeReordered(Id node_id,
327                               Id relative_node_id,
328                               OrderDirection direction,
329                               Id server_change_id) OVERRIDE {
330    tracker_.OnNodeReordered(node_id, relative_node_id, direction,
331                             server_change_id);
332  }
333  virtual void OnNodeDeleted(Id node, Id server_change_id) OVERRIDE {
334    tracker_.OnNodeDeleted(node, server_change_id);
335  }
336  virtual void OnViewDeleted(Id view) OVERRIDE {
337    tracker_.OnViewDeleted(view);
338  }
339  virtual void OnNodeViewReplaced(Id node,
340                                  Id new_view_id,
341                                  Id old_view_id) OVERRIDE {
342    tracker_.OnNodeViewReplaced(node, new_view_id, old_view_id);
343  }
344  virtual void OnViewInputEvent(Id view_id,
345                                EventPtr event,
346                                const Callback<void()>& callback) OVERRIDE {
347    tracker_.OnViewInputEvent(view_id, event.Pass());
348  }
349  virtual void DispatchOnViewInputEvent(Id view_id,
350                                        mojo::EventPtr event) OVERRIDE {
351  }
352
353 private:
354  TestChangeTracker tracker_;
355  ViewManagerProxy connection_;
356
357  DISALLOW_COPY_AND_ASSIGN(TestViewManagerClientConnection);
358};
359
360// Used with ViewManagerService::Embed(). Creates a
361// TestViewManagerClientConnection, which creates and owns the ViewManagerProxy.
362class EmbedServiceLoader : public ServiceLoader {
363 public:
364  EmbedServiceLoader() {}
365  virtual ~EmbedServiceLoader() {}
366
367  // ServiceLoader:
368  virtual void LoadService(ServiceManager* manager,
369                           const GURL& url,
370                           ScopedMessagePipeHandle shell_handle) OVERRIDE {
371    scoped_ptr<Application> app(new Application(shell_handle.Pass()));
372    app->AddService<TestViewManagerClientConnection>();
373    apps_.push_back(app.release());
374  }
375  virtual void OnServiceError(ServiceManager* manager,
376                              const GURL& url) OVERRIDE {
377  }
378
379 private:
380  ScopedVector<Application> apps_;
381
382  DISALLOW_COPY_AND_ASSIGN(EmbedServiceLoader);
383};
384
385// Creates an id used for transport from the specified parameters.
386Id BuildNodeId(ConnectionSpecificId connection_id,
387               ConnectionSpecificId node_id) {
388  return (connection_id << 16) | node_id;
389}
390
391// Creates an id used for transport from the specified parameters.
392Id BuildViewId(ConnectionSpecificId connection_id,
393               ConnectionSpecificId view_id) {
394  return (connection_id << 16) | view_id;
395}
396
397// Callback from EmbedRoot(). |result| is the result of the
398// Embed() call and |run_loop| the nested RunLoop.
399void EmbedRootCallback(bool* result_cache,
400                       base::RunLoop* run_loop,
401                       bool result) {
402  *result_cache = result;
403  run_loop->Quit();
404}
405
406// Resposible for establishing the initial ViewManagerService connection. Blocks
407// until result is determined.
408bool EmbedRoot(ViewManagerInitService* view_manager_init,
409               const std::string& url) {
410  bool result = false;
411  base::RunLoop run_loop;
412  view_manager_init->EmbedRoot(url, base::Bind(&EmbedRootCallback,
413                                               &result, &run_loop));
414  run_loop.Run();
415  return result;
416}
417
418}  // namespace
419
420typedef std::vector<std::string> Changes;
421
422class ViewManagerTest : public testing::Test {
423 public:
424  ViewManagerTest() : connection_(NULL), connection2_(NULL) {}
425
426  virtual void SetUp() OVERRIDE {
427    test_helper_.Init();
428
429    test_helper_.SetLoaderForURL(
430        scoped_ptr<ServiceLoader>(new EmbedServiceLoader()),
431        GURL(kTestServiceURL));
432
433    ConnectToService(test_helper_.service_provider(),
434                     "mojo:mojo_view_manager",
435                     &view_manager_init_);
436    ASSERT_TRUE(EmbedRoot(view_manager_init_.get(), kTestServiceURL));
437
438    connection_ = ViewManagerProxy::WaitForInstance();
439    ASSERT_TRUE(connection_ != NULL);
440    connection_->DoRunLoopUntilChangesCount(1);
441  }
442
443  virtual void TearDown() OVERRIDE {
444    if (connection2_)
445      connection2_->Destroy();
446    if (connection_)
447      connection_->Destroy();
448  }
449
450 protected:
451  void EstablishSecondConnectionWithRoots(Id id1, Id id2) {
452    std::vector<Id> node_ids;
453    node_ids.push_back(id1);
454    if (id2 != 0)
455      node_ids.push_back(id2);
456    ASSERT_TRUE(connection_->Embed(node_ids));
457    connection2_ = ViewManagerProxy::WaitForInstance();
458    ASSERT_TRUE(connection2_ != NULL);
459    connection2_->DoRunLoopUntilChangesCount(1);
460    ASSERT_EQ(1u, connection2_->changes().size());
461  }
462
463  // Creates a second connection to the viewmanager.
464  void EstablishSecondConnection(bool create_initial_node) {
465    if (create_initial_node)
466      ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
467    ASSERT_NO_FATAL_FAILURE(
468        EstablishSecondConnectionWithRoots(BuildNodeId(1, 1), 0));
469    const std::vector<Change>& changes(connection2_->changes());
470    ASSERT_EQ(1u, changes.size());
471    EXPECT_EQ("OnConnectionEstablished creator=mojo:test_url",
472              ChangesToDescription1(changes)[0]);
473    if (create_initial_node) {
474      EXPECT_EQ("[node=1,1 parent=null view=null]",
475                ChangeNodeDescription(changes));
476    }
477  }
478
479  void DestroySecondConnection() {
480    connection2_->Destroy();
481    connection2_ = NULL;
482  }
483
484  base::ShadowingAtExitManager at_exit_;
485  base::MessageLoop loop_;
486  shell::ShellTestHelper test_helper_;
487
488  ViewManagerInitServicePtr view_manager_init_;
489
490  ViewManagerProxy* connection_;
491  ViewManagerProxy* connection2_;
492
493  DISALLOW_COPY_AND_ASSIGN(ViewManagerTest);
494};
495
496// TODO(sky): reenable tests: http://crbug.com/385475
497
498// Verifies client gets a valid id.
499TEST_F(ViewManagerTest, DISABLED_ValidId) {
500  // TODO(beng): this should really have the URL of the application that
501  //             connected to ViewManagerInit.
502  EXPECT_EQ("OnConnectionEstablished creator=",
503            ChangesToDescription1(connection_->changes())[0]);
504
505  // All these tests assume 1 for the client id. The only real assertion here is
506  // the client id is not zero, but adding this as rest of code here assumes 1.
507  EXPECT_EQ(1, connection_->changes()[0].connection_id);
508
509  // Change ids start at 1 as well.
510  EXPECT_EQ(static_cast<Id>(1), connection_->changes()[0].change_id);
511}
512
513// Verifies two clients/connections get different ids.
514TEST_F(ViewManagerTest, DISABLED_TwoClientsGetDifferentConnectionIds) {
515  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
516  EXPECT_EQ("OnConnectionEstablished creator=mojo:test_url",
517            ChangesToDescription1(connection2_->changes())[0]);
518
519  // It isn't strickly necessary that the second connection gets 2, but these
520  // tests are written assuming that is the case. The key thing is the
521  // connection ids of |connection_| and |connection2_| differ.
522  EXPECT_EQ(2, connection2_->changes()[0].connection_id);
523
524  // Change ids start at 1 as well.
525  EXPECT_EQ(static_cast<Id>(1), connection2_->changes()[0].change_id);
526}
527
528// Verifies client gets a valid id.
529TEST_F(ViewManagerTest, DISABLED_CreateNode) {
530  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
531  EXPECT_TRUE(connection_->changes().empty());
532
533  // Can't create a node with the same id.
534  ASSERT_FALSE(connection_->CreateNode(BuildNodeId(1, 1)));
535  EXPECT_TRUE(connection_->changes().empty());
536
537  // Can't create a node with a bogus connection id.
538  EXPECT_FALSE(connection_->CreateNode(BuildNodeId(2, 1)));
539  EXPECT_TRUE(connection_->changes().empty());
540}
541
542TEST_F(ViewManagerTest, DISABLED_CreateViewFailsWithBogusConnectionId) {
543  EXPECT_FALSE(connection_->CreateView(BuildViewId(2, 1)));
544  EXPECT_TRUE(connection_->changes().empty());
545}
546
547// Verifies hierarchy changes.
548TEST_F(ViewManagerTest, DISABLED_AddRemoveNotify) {
549  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
550  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3)));
551
552  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
553
554  // Make 3 a child of 2.
555  {
556    ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 3), 1));
557    EXPECT_TRUE(connection_->changes().empty());
558
559    connection2_->DoRunLoopUntilChangesCount(1);
560    const Changes changes(ChangesToDescription1(connection2_->changes()));
561    ASSERT_EQ(1u, changes.size());
562    EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]);
563  }
564
565  // Remove 3 from its parent.
566  {
567    ASSERT_TRUE(connection_->RemoveNodeFromParent(BuildNodeId(1, 3), 2));
568    EXPECT_TRUE(connection_->changes().empty());
569
570    connection2_->DoRunLoopUntilChangesCount(1);
571    const Changes changes(ChangesToDescription1(connection2_->changes()));
572    ASSERT_EQ(1u, changes.size());
573    EXPECT_EQ("ServerChangeIdAdvanced 3", changes[0]);
574  }
575}
576
577// Verifies AddNode fails when node is already in position.
578TEST_F(ViewManagerTest, DISABLED_AddNodeWithNoChange) {
579  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
580  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3)));
581
582  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
583
584  // Make 3 a child of 2.
585  {
586    ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 3), 1));
587
588    connection2_->DoRunLoopUntilChangesCount(1);
589    const Changes changes(ChangesToDescription1(connection2_->changes()));
590    ASSERT_EQ(1u, changes.size());
591    EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]);
592  }
593
594  // Try again, this should fail.
595  {
596    EXPECT_FALSE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 3), 2));
597  }
598}
599
600// Verifies AddNode fails when node is already in position.
601TEST_F(ViewManagerTest, DISABLED_AddAncestorFails) {
602  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
603  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3)));
604
605  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
606
607  // Make 3 a child of 2.
608  {
609    ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 3), 1));
610    connection2_->DoRunLoopUntilChangesCount(1);
611    const Changes changes(ChangesToDescription1(connection2_->changes()));
612    ASSERT_EQ(1u, changes.size());
613    EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]);
614  }
615
616  // Try to make 2 a child of 3, this should fail since 2 is an ancestor of 3.
617  {
618    EXPECT_FALSE(connection_->AddNode(BuildNodeId(1, 3), BuildNodeId(1, 2), 2));
619  }
620}
621
622// Verifies adding with an invalid id fails.
623TEST_F(ViewManagerTest, DISABLED_AddWithInvalidServerId) {
624  // Create two nodes.
625  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
626  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
627
628  // Make 2 a child of 1. Supply an invalid change id, which should fail.
629  ASSERT_FALSE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 0));
630}
631
632// Verifies adding to root sends right notifications.
633TEST_F(ViewManagerTest, DISABLED_AddToRoot) {
634  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 21)));
635  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3)));
636
637  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
638
639  // Make 3 a child of 21.
640  {
641    ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 21), BuildNodeId(1, 3), 1));
642
643    connection2_->DoRunLoopUntilChangesCount(1);
644    const Changes changes(ChangesToDescription1(connection2_->changes()));
645    ASSERT_EQ(1u, changes.size());
646    EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]);
647  }
648
649  // Make 21 a child of 1.
650  {
651    ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 21), 2));
652
653    connection2_->DoRunLoopUntilChangesCount(1);
654    const Changes changes(ChangesToDescription1(connection2_->changes()));
655    ASSERT_EQ(1u, changes.size());
656    EXPECT_EQ(
657        "HierarchyChanged change_id=2 node=1,21 new_parent=1,1 old_parent=null",
658        changes[0]);
659  }
660}
661
662// Verifies HierarchyChanged is correctly sent for various adds/removes.
663TEST_F(ViewManagerTest, DISABLED_NodeHierarchyChangedNodes) {
664  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
665  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 11)));
666  // Make 11 a child of 2.
667  ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 11), 1));
668
669  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
670
671  // Make 2 a child of 1.
672  {
673    ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 2));
674
675    // Client 2 should get a hierarchy change that includes the new nodes as it
676    // has not yet seen them.
677    connection2_->DoRunLoopUntilChangesCount(1);
678    const Changes changes(ChangesToDescription1(connection2_->changes()));
679    ASSERT_EQ(1u, changes.size());
680    EXPECT_EQ(
681        "HierarchyChanged change_id=2 node=1,2 new_parent=1,1 old_parent=null",
682        changes[0]);
683    EXPECT_EQ("[node=1,2 parent=1,1 view=null],"
684              "[node=1,11 parent=1,2 view=null]",
685              ChangeNodeDescription(connection2_->changes()));
686  }
687
688  // Add 1 to the root.
689  {
690    ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 3));
691
692    // Client 2 should get a hierarchy change that includes the new nodes as it
693    // has not yet seen them.
694    connection2_->DoRunLoopUntilChangesCount(1);
695    const Changes changes(ChangesToDescription1(connection2_->changes()));
696    ASSERT_EQ(1u, changes.size());
697    EXPECT_EQ(
698        "HierarchyChanged change_id=3 node=1,1 new_parent=null old_parent=null",
699        changes[0]);
700    EXPECT_EQ(std::string(), ChangeNodeDescription(connection2_->changes()));
701  }
702
703  // Remove 1 from its parent.
704  {
705    ASSERT_TRUE(connection_->RemoveNodeFromParent(BuildNodeId(1, 1), 4));
706    EXPECT_TRUE(connection_->changes().empty());
707
708    connection2_->DoRunLoopUntilChangesCount(1);
709    const Changes changes(ChangesToDescription1(connection2_->changes()));
710    ASSERT_EQ(1u, changes.size());
711    EXPECT_EQ(
712        "HierarchyChanged change_id=4 node=1,1 new_parent=null old_parent=null",
713        changes[0]);
714  }
715
716  // Create another node, 111, parent it to 11.
717  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 111)));
718  {
719    ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 11), BuildNodeId(1, 111),
720                                     5));
721
722    connection2_->DoRunLoopUntilChangesCount(1);
723    const Changes changes(ChangesToDescription1(connection2_->changes()));
724    ASSERT_EQ(1u, changes.size());
725    EXPECT_EQ(
726        "HierarchyChanged change_id=5 node=1,111 new_parent=1,11 "
727        "old_parent=null", changes[0]);
728    EXPECT_EQ("[node=1,111 parent=1,11 view=null]",
729              ChangeNodeDescription(connection2_->changes()));
730  }
731
732  // Reattach 1 to the root.
733  {
734    ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 6));
735
736    connection2_->DoRunLoopUntilChangesCount(1);
737    const Changes changes(ChangesToDescription1(connection2_->changes()));
738    ASSERT_EQ(1u, changes.size());
739    EXPECT_EQ(
740        "HierarchyChanged change_id=6 node=1,1 new_parent=null old_parent=null",
741        changes[0]);
742    EXPECT_EQ(std::string(), ChangeNodeDescription(connection2_->changes()));
743  }
744}
745
746TEST_F(ViewManagerTest, DISABLED_NodeHierarchyChangedAddingKnownToUnknown) {
747  // Create the following structure: root -> 1 -> 11 and 2->21 (2 has no
748  // parent).
749  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
750  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 11)));
751  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
752  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 21)));
753
754  // Set up the hierarchy.
755  ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1));
756  ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 11), 2));
757  ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 21), 3));
758
759  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
760  {
761    EXPECT_EQ("[node=1,1 parent=null view=null],"
762              "[node=1,11 parent=1,1 view=null]",
763              ChangeNodeDescription(connection2_->changes()));
764  }
765
766  // Remove 11, should result in a delete (since 11 is no longer in connection
767  // 2's root).
768  {
769    ASSERT_TRUE(connection_->RemoveNodeFromParent(BuildNodeId(1, 11), 4));
770
771    connection2_->DoRunLoopUntilChangesCount(1);
772    const Changes changes(ChangesToDescription1(connection2_->changes()));
773    ASSERT_EQ(1u, changes.size());
774    EXPECT_EQ("NodeDeleted change_id=4 node=1,11", changes[0]);
775  }
776
777  // Add 2 to 1.
778  {
779    ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 5));
780
781    connection2_->DoRunLoopUntilChangesCount(1);
782    const Changes changes(ChangesToDescription1(connection2_->changes()));
783    ASSERT_EQ(1u, changes.size());
784    EXPECT_EQ(
785        "HierarchyChanged change_id=5 node=1,2 new_parent=1,1 old_parent=null",
786        changes[0]);
787    EXPECT_EQ("[node=1,2 parent=1,1 view=null],"
788              "[node=1,21 parent=1,2 view=null]",
789              ChangeNodeDescription(connection2_->changes()));
790  }
791}
792
793TEST_F(ViewManagerTest, DISABLED_ReorderNode) {
794  Id node1_id = BuildNodeId(1, 1);
795  Id node2_id = BuildNodeId(1, 2);
796  Id node3_id = BuildNodeId(1, 3);
797  Id node4_id = BuildNodeId(1, 4);  // Peer to 1,1
798  Id node5_id = BuildNodeId(1, 5);  // Peer to 1,1
799  Id node6_id = BuildNodeId(1, 6);  // Child of 1,2.
800  Id node7_id = BuildNodeId(1, 7);  // Unparented.
801  Id node8_id = BuildNodeId(1, 8);  // Unparented.
802  ASSERT_TRUE(connection_->CreateNode(node1_id));
803  ASSERT_TRUE(connection_->CreateNode(node2_id));
804  ASSERT_TRUE(connection_->CreateNode(node3_id));
805  ASSERT_TRUE(connection_->CreateNode(node4_id));
806  ASSERT_TRUE(connection_->CreateNode(node5_id));
807  ASSERT_TRUE(connection_->CreateNode(node6_id));
808  ASSERT_TRUE(connection_->CreateNode(node7_id));
809  ASSERT_TRUE(connection_->CreateNode(node8_id));
810  ASSERT_TRUE(connection_->AddNode(node1_id, node2_id, 1));
811  ASSERT_TRUE(connection_->AddNode(node2_id, node6_id, 2));
812  ASSERT_TRUE(connection_->AddNode(node1_id, node3_id, 3));
813  ASSERT_TRUE(connection_->AddNode(
814      NodeIdToTransportId(RootNodeId()), node4_id, 4));
815  ASSERT_TRUE(connection_->AddNode(
816      NodeIdToTransportId(RootNodeId()), node5_id, 5));
817
818  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
819
820  {
821    connection_->ReorderNode(node2_id, node3_id, ORDER_ABOVE, 6);
822
823    connection2_->DoRunLoopUntilChangesCount(1);
824    const Changes changes(ChangesToDescription1(connection2_->changes()));
825    ASSERT_EQ(1u, changes.size());
826    EXPECT_EQ(
827        "Reordered change_id=6 node=1,2 relative=1,3 direction=above",
828        changes[0]);
829  }
830
831  {
832    connection_->ReorderNode(node2_id, node3_id, ORDER_BELOW, 7);
833
834    connection2_->DoRunLoopUntilChangesCount(1);
835    const Changes changes(ChangesToDescription1(connection2_->changes()));
836    ASSERT_EQ(1u, changes.size());
837    EXPECT_EQ(
838        "Reordered change_id=7 node=1,2 relative=1,3 direction=below",
839        changes[0]);
840  }
841
842  {
843    // node2 is already below node3.
844    EXPECT_FALSE(connection_->ReorderNode(node2_id, node3_id, ORDER_BELOW, 8));
845  }
846
847  {
848    // node4 & 5 are unknown to connection2_.
849    EXPECT_FALSE(connection2_->ReorderNode(node4_id, node5_id, ORDER_ABOVE, 8));
850  }
851
852  {
853    // node6 & node3 have different parents.
854    EXPECT_FALSE(connection_->ReorderNode(node3_id, node6_id, ORDER_ABOVE, 8));
855  }
856
857  {
858    // Non-existent node-ids
859    EXPECT_FALSE(connection_->ReorderNode(BuildNodeId(1, 27),
860                                          BuildNodeId(1, 28),
861                                          ORDER_ABOVE,
862                                          8));
863  }
864
865  {
866    // node7 & node8 are un-parented.
867    EXPECT_FALSE(connection_->ReorderNode(node7_id, node8_id, ORDER_ABOVE, 8));
868  }
869}
870
871// Verifies DeleteNode works.
872TEST_F(ViewManagerTest, DISABLED_DeleteNode) {
873  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
874
875  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
876
877  // Make 2 a child of 1.
878  {
879    ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 1));
880    connection2_->DoRunLoopUntilChangesCount(1);
881    const Changes changes(ChangesToDescription1(connection2_->changes()));
882    ASSERT_EQ(1u, changes.size());
883    EXPECT_EQ("HierarchyChanged change_id=1 node=1,2 new_parent=1,1 "
884              "old_parent=null", changes[0]);
885  }
886
887  // Delete 2.
888  {
889    ASSERT_TRUE(connection_->DeleteNode(BuildNodeId(1, 2), 2));
890    EXPECT_TRUE(connection_->changes().empty());
891
892    connection2_->DoRunLoopUntilChangesCount(1);
893    const Changes changes(ChangesToDescription1(connection2_->changes()));
894    ASSERT_EQ(1u, changes.size());
895    EXPECT_EQ("NodeDeleted change_id=2 node=1,2", changes[0]);
896  }
897}
898
899// Verifies DeleteNode isn't allowed from a separate connection.
900TEST_F(ViewManagerTest, DISABLED_DeleteNodeFromAnotherConnectionDisallowed) {
901  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
902  EXPECT_FALSE(connection2_->DeleteNode(BuildNodeId(1, 1), 1));
903}
904
905// Verifies DeleteView isn't allowed from a separate connection.
906TEST_F(ViewManagerTest, DISABLED_DeleteViewFromAnotherConnectionDisallowed) {
907  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1)));
908  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
909  EXPECT_FALSE(connection2_->DeleteView(BuildViewId(1, 1)));
910}
911
912// Verifies if a node was deleted and then reused that other clients are
913// properly notified.
914TEST_F(ViewManagerTest, DISABLED_ReuseDeletedNodeId) {
915  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
916  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
917
918  // Add 2 to 1.
919  {
920    ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 1));
921
922    connection2_->DoRunLoopUntilChangesCount(1);
923    const Changes changes(ChangesToDescription1(connection2_->changes()));
924    EXPECT_EQ(
925        "HierarchyChanged change_id=1 node=1,2 new_parent=1,1 old_parent=null",
926        changes[0]);
927    EXPECT_EQ("[node=1,2 parent=1,1 view=null]",
928              ChangeNodeDescription(connection2_->changes()));
929  }
930
931  // Delete 2.
932  {
933    ASSERT_TRUE(connection_->DeleteNode(BuildNodeId(1, 2), 2));
934
935    connection2_->DoRunLoopUntilChangesCount(1);
936    const Changes changes(ChangesToDescription1(connection2_->changes()));
937    ASSERT_EQ(1u, changes.size());
938    EXPECT_EQ("NodeDeleted change_id=2 node=1,2", changes[0]);
939  }
940
941  // Create 2 again, and add it back to 1. Should get the same notification.
942  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
943  {
944    ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 3));
945
946    connection2_->DoRunLoopUntilChangesCount(1);
947    const Changes changes(ChangesToDescription1(connection2_->changes()));
948    EXPECT_EQ(
949        "HierarchyChanged change_id=3 node=1,2 new_parent=1,1 old_parent=null",
950        changes[0]);
951    EXPECT_EQ("[node=1,2 parent=1,1 view=null]",
952              ChangeNodeDescription(connection2_->changes()));
953  }
954}
955
956// Assertions around setting a view.
957TEST_F(ViewManagerTest, DISABLED_SetView) {
958  // Create nodes 1, 2 and 3 and the view 11. Nodes 2 and 3 are parented to 1.
959  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
960  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
961  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3)));
962  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 11)));
963  ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 1));
964  ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 3), 2));
965
966  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
967
968  // Set view 11 on node 1.
969  {
970    ASSERT_TRUE(connection_->SetView(BuildNodeId(1, 1),
971                                     BuildViewId(1, 11)));
972
973    connection2_->DoRunLoopUntilChangesCount(1);
974    const Changes changes(ChangesToDescription1(connection2_->changes()));
975    ASSERT_EQ(1u, changes.size());
976    EXPECT_EQ("ViewReplaced node=1,1 new_view=1,11 old_view=null",
977              changes[0]);
978  }
979
980  // Set view 11 on node 2.
981  {
982    ASSERT_TRUE(connection_->SetView(BuildNodeId(1, 2), BuildViewId(1, 11)));
983
984    connection2_->DoRunLoopUntilChangesCount(2);
985    const Changes changes(ChangesToDescription1(connection2_->changes()));
986    ASSERT_EQ(2u, changes.size());
987    EXPECT_EQ("ViewReplaced node=1,1 new_view=null old_view=1,11",
988              changes[0]);
989    EXPECT_EQ("ViewReplaced node=1,2 new_view=1,11 old_view=null",
990              changes[1]);
991  }
992}
993
994// Verifies deleting a node with a view sends correct notifications.
995TEST_F(ViewManagerTest, DISABLED_DeleteNodeWithView) {
996  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
997  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
998  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3)));
999  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 11)));
1000
1001  // Set view 11 on node 2.
1002  ASSERT_TRUE(connection_->SetView(BuildNodeId(1, 2), BuildViewId(1, 11)));
1003
1004  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
1005
1006  // Delete node 2. The second connection should not see this because the node
1007  // was not known to it.
1008  {
1009    ASSERT_TRUE(connection_->DeleteNode(BuildNodeId(1, 2), 1));
1010
1011    connection2_->DoRunLoopUntilChangesCount(1);
1012    const Changes changes(ChangesToDescription1(connection2_->changes()));
1013    ASSERT_EQ(1u, changes.size());
1014    EXPECT_EQ("ServerChangeIdAdvanced 2", changes[0]);
1015  }
1016
1017  // Parent 3 to 1.
1018  ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 3), 2));
1019  connection2_->DoRunLoopUntilChangesCount(1);
1020
1021  // Set view 11 on node 3.
1022  {
1023    ASSERT_TRUE(connection_->SetView(BuildNodeId(1, 3), BuildViewId(1, 11)));
1024
1025    connection2_->DoRunLoopUntilChangesCount(1);
1026    const Changes changes(ChangesToDescription1(connection2_->changes()));
1027    ASSERT_EQ(1u, changes.size());
1028    EXPECT_EQ("ViewReplaced node=1,3 new_view=1,11 old_view=null", changes[0]);
1029  }
1030
1031  // Delete 3.
1032  {
1033    ASSERT_TRUE(connection_->DeleteNode(BuildNodeId(1, 3), 3));
1034
1035    connection2_->DoRunLoopUntilChangesCount(1);
1036    const Changes changes(ChangesToDescription1(connection2_->changes()));
1037    ASSERT_EQ(1u, changes.size());
1038    EXPECT_EQ("NodeDeleted change_id=3 node=1,3", changes[0]);
1039  }
1040}
1041
1042// Sets view from one connection on another.
1043TEST_F(ViewManagerTest, DISABLED_SetViewFromSecondConnection) {
1044  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
1045
1046  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
1047
1048  // Create a view in the second connection.
1049  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 51)));
1050
1051  // Attach view to node 1 in the first connection.
1052  {
1053    ASSERT_TRUE(connection2_->SetView(BuildNodeId(1, 1), BuildViewId(2, 51)));
1054    connection_->DoRunLoopUntilChangesCount(1);
1055    const Changes changes(ChangesToDescription1(connection_->changes()));
1056    ASSERT_EQ(1u, changes.size());
1057    EXPECT_EQ("ViewReplaced node=1,1 new_view=2,51 old_view=null", changes[0]);
1058  }
1059
1060  // Shutdown the second connection and verify view is removed.
1061  {
1062    DestroySecondConnection();
1063    connection_->DoRunLoopUntilChangesCount(2);
1064    const Changes changes(ChangesToDescription1(connection_->changes()));
1065    ASSERT_EQ(2u, changes.size());
1066    EXPECT_EQ("ViewReplaced node=1,1 new_view=null old_view=2,51", changes[0]);
1067    EXPECT_EQ("ViewDeleted view=2,51", changes[1]);
1068  }
1069}
1070
1071// Assertions for GetNodeTree.
1072TEST_F(ViewManagerTest, DISABLED_GetNodeTree) {
1073  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
1074
1075  // Create 11 in first connection and make it a child of 1.
1076  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 11)));
1077  ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1));
1078  ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 11), 2));
1079
1080  // Create two nodes in second connection, 2 and 3, both children of 1.
1081  ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 2)));
1082  ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 3)));
1083  ASSERT_TRUE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(2, 2), 3));
1084  ASSERT_TRUE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(2, 3), 4));
1085
1086  // Attach view to node 11 in the first connection.
1087  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 51)));
1088  ASSERT_TRUE(connection_->SetView(BuildNodeId(1, 11), BuildViewId(1, 51)));
1089
1090  // Verifies GetNodeTree() on the root.
1091  {
1092    std::vector<TestNode> nodes;
1093    connection_->GetNodeTree(BuildNodeId(0, 1), &nodes);
1094    ASSERT_EQ(5u, nodes.size());
1095    EXPECT_EQ("node=0,1 parent=null view=null", nodes[0].ToString());
1096    EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[1].ToString());
1097    EXPECT_EQ("node=1,11 parent=1,1 view=1,51", nodes[2].ToString());
1098    EXPECT_EQ("node=2,2 parent=1,1 view=null", nodes[3].ToString());
1099    EXPECT_EQ("node=2,3 parent=1,1 view=null", nodes[4].ToString());
1100  }
1101
1102  // Verifies GetNodeTree() on the node 1,1.
1103  {
1104    std::vector<TestNode> nodes;
1105    connection2_->GetNodeTree(BuildNodeId(1, 1), &nodes);
1106    ASSERT_EQ(4u, nodes.size());
1107    EXPECT_EQ("node=1,1 parent=null view=null", nodes[0].ToString());
1108    EXPECT_EQ("node=1,11 parent=1,1 view=1,51", nodes[1].ToString());
1109    EXPECT_EQ("node=2,2 parent=1,1 view=null", nodes[2].ToString());
1110    EXPECT_EQ("node=2,3 parent=1,1 view=null", nodes[3].ToString());
1111  }
1112
1113  // Connection 2 shouldn't be able to get the root tree.
1114  {
1115    std::vector<TestNode> nodes;
1116    connection2_->GetNodeTree(BuildNodeId(0, 1), &nodes);
1117    ASSERT_EQ(0u, nodes.size());
1118  }
1119}
1120
1121TEST_F(ViewManagerTest, DISABLED_SetNodeBounds) {
1122  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
1123  ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1));
1124
1125  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
1126
1127  ASSERT_TRUE(connection_->SetNodeBounds(BuildNodeId(1, 1),
1128                                         gfx::Rect(0, 0, 100, 100)));
1129
1130  connection2_->DoRunLoopUntilChangesCount(1);
1131  const Changes changes(ChangesToDescription1(connection2_->changes()));
1132  ASSERT_EQ(1u, changes.size());
1133  EXPECT_EQ("BoundsChanged node=1,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100",
1134            changes[0]);
1135
1136  // Should not be possible to change the bounds of a node created by another
1137  // connection.
1138  ASSERT_FALSE(connection2_->SetNodeBounds(BuildNodeId(1, 1),
1139                                           gfx::Rect(0, 0, 0, 0)));
1140}
1141
1142// Various assertions around SetRoots.
1143TEST_F(ViewManagerTest, DISABLED_SetRoots) {
1144  // Create 1, 2, and 3 in the first connection.
1145  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
1146  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
1147  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 3)));
1148
1149  // Parent 1 to the root.
1150  ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1));
1151
1152  // Establish the second connection and give it the roots 1 and 3.
1153  {
1154    ASSERT_NO_FATAL_FAILURE(EstablishSecondConnectionWithRoots(
1155                                BuildNodeId(1, 1), BuildNodeId(1, 3)));
1156    const Changes changes(ChangesToDescription1(connection2_->changes()));
1157    ASSERT_EQ(1u, changes.size());
1158    EXPECT_EQ("OnConnectionEstablished creator=mojo:test_url", changes[0]);
1159    EXPECT_EQ("[node=1,1 parent=null view=null],"
1160              "[node=1,3 parent=null view=null]",
1161              ChangeNodeDescription(connection2_->changes()));
1162  }
1163
1164  // Create 4 and add it to the root, connection 2 should only get id advanced.
1165  {
1166    ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 4)));
1167    ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 4), 2));
1168
1169    connection2_->DoRunLoopUntilChangesCount(1);
1170    const Changes changes(ChangesToDescription1(connection2_->changes()));
1171    ASSERT_EQ(1u, changes.size());
1172    EXPECT_EQ("ServerChangeIdAdvanced 3", changes[0]);
1173  }
1174
1175  // Move 4 under 3, this should expose 4 to the client.
1176  {
1177    ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 3), BuildNodeId(1, 4), 3));
1178    connection2_->DoRunLoopUntilChangesCount(1);
1179    const Changes changes(ChangesToDescription1(connection2_->changes()));
1180    ASSERT_EQ(1u, changes.size());
1181    EXPECT_EQ(
1182        "HierarchyChanged change_id=3 node=1,4 new_parent=1,3 "
1183        "old_parent=null", changes[0]);
1184    EXPECT_EQ("[node=1,4 parent=1,3 view=null]",
1185              ChangeNodeDescription(connection2_->changes()));
1186  }
1187
1188  // Move 4 under 2, since 2 isn't a root client should get a delete.
1189  {
1190    ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 2), BuildNodeId(1, 4), 4));
1191    connection2_->DoRunLoopUntilChangesCount(1);
1192    const Changes changes(ChangesToDescription1(connection2_->changes()));
1193    ASSERT_EQ(1u, changes.size());
1194    EXPECT_EQ("NodeDeleted change_id=4 node=1,4", changes[0]);
1195  }
1196
1197  // Delete 4, client shouldn't receive a delete since it should no longer know
1198  // about 4.
1199  {
1200    ASSERT_TRUE(connection_->DeleteNode(BuildNodeId(1, 4), 5));
1201
1202    connection2_->DoRunLoopUntilChangesCount(1);
1203    const Changes changes(ChangesToDescription1(connection2_->changes()));
1204    ASSERT_EQ(1u, changes.size());
1205    EXPECT_EQ("ServerChangeIdAdvanced 6", changes[0]);
1206  }
1207}
1208
1209// Verify AddNode fails when trying to manipulate nodes in other roots.
1210TEST_F(ViewManagerTest, DISABLED_CantMoveNodesFromOtherRoot) {
1211  // Create 1 and 2 in the first connection.
1212  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
1213  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
1214
1215  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
1216
1217  // Try to move 2 to be a child of 1 from connection 2. This should fail as 2
1218  // should not be able to access 1.
1219  ASSERT_FALSE(connection2_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 1));
1220
1221  // Try to reparent 1 to the root. A connection is not allowed to reparent its
1222  // roots.
1223  ASSERT_FALSE(connection2_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1));
1224}
1225
1226// Verify RemoveNodeFromParent fails for nodes that are descendants of the
1227// roots.
1228TEST_F(ViewManagerTest, DISABLED_CantRemoveNodesInOtherRoots) {
1229  // Create 1 and 2 in the first connection and parent both to the root.
1230  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
1231  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
1232
1233  ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1));
1234  ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 2), 2));
1235
1236  // Establish the second connection and give it the root 1.
1237  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
1238
1239  // Connection 2 should not be able to remove node 2 or 1 from its parent.
1240  ASSERT_FALSE(connection2_->RemoveNodeFromParent(BuildNodeId(1, 2), 3));
1241  ASSERT_FALSE(connection2_->RemoveNodeFromParent(BuildNodeId(1, 1), 3));
1242
1243  // Create nodes 10 and 11 in 2.
1244  ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 10)));
1245  ASSERT_TRUE(connection2_->CreateNode(BuildNodeId(2, 11)));
1246
1247  // Parent 11 to 10.
1248  ASSERT_TRUE(connection2_->AddNode(BuildNodeId(2, 10), BuildNodeId(2, 11), 3));
1249  // Remove 11 from 10.
1250  ASSERT_TRUE(connection2_->RemoveNodeFromParent( BuildNodeId(2, 11), 4));
1251
1252  // Verify nothing was actually removed.
1253  {
1254    std::vector<TestNode> nodes;
1255    connection_->GetNodeTree(BuildNodeId(0, 1), &nodes);
1256    ASSERT_EQ(3u, nodes.size());
1257    EXPECT_EQ("node=0,1 parent=null view=null", nodes[0].ToString());
1258    EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[1].ToString());
1259    EXPECT_EQ("node=1,2 parent=0,1 view=null", nodes[2].ToString());
1260  }
1261}
1262
1263// Verify SetView fails for nodes that are not descendants of the roots.
1264TEST_F(ViewManagerTest, DISABLED_CantRemoveSetViewInOtherRoots) {
1265  // Create 1 and 2 in the first connection and parent both to the root.
1266  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
1267  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
1268
1269  ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1));
1270  ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 2), 2));
1271
1272  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
1273
1274  // Create a view in the second connection.
1275  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 51)));
1276
1277  // Connection 2 should be able to set the view on node 1 (it's root), but not
1278  // on 2.
1279  ASSERT_TRUE(connection2_->SetView(BuildNodeId(1, 1), BuildViewId(2, 51)));
1280  ASSERT_FALSE(connection2_->SetView(BuildNodeId(1, 2), BuildViewId(2, 51)));
1281}
1282
1283// Verify GetNodeTree fails for nodes that are not descendants of the roots.
1284TEST_F(ViewManagerTest, DISABLED_CantGetNodeTreeOfOtherRoots) {
1285  // Create 1 and 2 in the first connection and parent both to the root.
1286  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
1287  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
1288
1289  ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 1), 1));
1290  ASSERT_TRUE(connection_->AddNode(BuildNodeId(0, 1), BuildNodeId(1, 2), 2));
1291
1292  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
1293
1294  std::vector<TestNode> nodes;
1295
1296  // Should get nothing for the root.
1297  connection2_->GetNodeTree(BuildNodeId(0, 1), &nodes);
1298  ASSERT_TRUE(nodes.empty());
1299
1300  // Should get nothing for node 2.
1301  connection2_->GetNodeTree(BuildNodeId(1, 2), &nodes);
1302  ASSERT_TRUE(nodes.empty());
1303
1304  // Should get node 1 if asked for.
1305  connection2_->GetNodeTree(BuildNodeId(1, 1), &nodes);
1306  ASSERT_EQ(1u, nodes.size());
1307  EXPECT_EQ("node=1,1 parent=null view=null", nodes[0].ToString());
1308}
1309
1310TEST_F(ViewManagerTest, DISABLED_ConnectTwice) {
1311  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
1312  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2)));
1313
1314  ASSERT_TRUE(connection_->AddNode(BuildNodeId(1, 1), BuildNodeId(1, 2), 1));
1315
1316  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
1317
1318  // Try to connect again to 1,1, this should fail as already connected to that
1319  // root.
1320  {
1321    std::vector<Id> node_ids;
1322    node_ids.push_back(BuildNodeId(1, 1));
1323    ASSERT_FALSE(connection_->Embed(node_ids));
1324  }
1325
1326  // Connecting to 1,2 should succeed and end up in connection2.
1327  {
1328    std::vector<Id> node_ids;
1329    node_ids.push_back(BuildNodeId(1, 2));
1330    ASSERT_TRUE(connection_->Embed(node_ids));
1331    connection2_->DoRunLoopUntilChangesCount(1);
1332    const Changes changes(ChangesToDescription1(connection2_->changes()));
1333    ASSERT_EQ(1u, changes.size());
1334    EXPECT_EQ("OnRootsAdded", changes[0]);
1335    EXPECT_EQ("[node=1,2 parent=1,1 view=null]",
1336              ChangeNodeDescription(connection2_->changes()));
1337  }
1338}
1339
1340TEST_F(ViewManagerTest, DISABLED_OnViewInput) {
1341  // Create node 1 and assign a view from connection 2 to it.
1342  ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1)));
1343  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
1344  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 11)));
1345  ASSERT_TRUE(connection2_->SetView(BuildNodeId(1, 1), BuildViewId(2, 11)));
1346
1347  // Dispatch an event to the view and verify its received.
1348  {
1349    EventPtr event(Event::New());
1350    event->action = 1;
1351    connection_->view_manager()->DispatchOnViewInputEvent(
1352        BuildViewId(2, 11),
1353        event.Pass());
1354    connection2_->DoRunLoopUntilChangesCount(1);
1355    const Changes changes(ChangesToDescription1(connection2_->changes()));
1356    ASSERT_EQ(1u, changes.size());
1357    EXPECT_EQ("InputEvent view=2,11 event_action=1", changes[0]);
1358  }
1359}
1360
1361// TODO(sky): add coverage of test that destroys connections and ensures other
1362// connections get deletion notification (or advanced server id).
1363
1364// TODO(sky): need to better track changes to initial connection. For example,
1365// that SetBounsdNodes/AddNode and the like don't result in messages to the
1366// originating connection.
1367
1368}  // namespace service
1369}  // namespace view_manager
1370}  // namespace mojo
1371