1// Copyright (c) 2012 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 "jingle/notifier/base/weak_xmpp_client.h"
6
7#include "base/basictypes.h"
8#include "base/memory/scoped_ptr.h"
9#include "base/memory/weak_ptr.h"
10#include "base/message_loop/message_loop.h"
11#include "jingle/glue/task_pump.h"
12#include "testing/gmock/include/gmock/gmock.h"
13#include "testing/gtest/include/gtest/gtest.h"
14#include "webrtc/base/sigslot.h"
15
16namespace notifier {
17
18namespace {
19
20class MockXmppDelegate : public sigslot::has_slots<> {
21 public:
22  virtual ~MockXmppDelegate() {}
23
24  MOCK_METHOD1(OnStateChange, void(buzz::XmppEngine::State));
25  MOCK_METHOD2(OnInputLog, void(const char*, int));
26  MOCK_METHOD2(OnOutputLog, void(const char*, int));
27};
28
29const buzz::XmppEngine::State kState = buzz::XmppEngine::STATE_OPEN;
30const char kInputLog[] = "input log";
31const char kOutputLog[] = "output log";
32
33class WeakXmppClientTest : public testing::Test {
34 protected:
35  WeakXmppClientTest() : task_pump_(new jingle_glue::TaskPump()) {}
36
37  virtual ~WeakXmppClientTest() {}
38
39  void ConnectSignals(buzz::XmppClient* xmpp_client) {
40    xmpp_client->SignalStateChange.connect(
41        &mock_xmpp_delegate_, &MockXmppDelegate::OnStateChange);
42    xmpp_client->SignalLogInput.connect(
43        &mock_xmpp_delegate_, &MockXmppDelegate::OnInputLog);
44    xmpp_client->SignalLogOutput.connect(
45        &mock_xmpp_delegate_, &MockXmppDelegate::OnOutputLog);
46  }
47
48  void ExpectSignalCalls() {
49    EXPECT_CALL(mock_xmpp_delegate_, OnStateChange(kState));
50    EXPECT_CALL(mock_xmpp_delegate_,
51                OnInputLog(kInputLog, arraysize(kInputLog)));
52    EXPECT_CALL(mock_xmpp_delegate_,
53                OnOutputLog(kOutputLog, arraysize(kOutputLog)));
54  }
55
56  void RaiseSignals(buzz::XmppClient* xmpp_client) {
57    xmpp_client->SignalStateChange(kState);
58    xmpp_client->SignalLogInput(kInputLog, arraysize(kInputLog));
59    xmpp_client->SignalLogOutput(kOutputLog, arraysize(kOutputLog));
60  }
61
62  // Needed by TaskPump.
63  base::MessageLoop message_loop_;
64
65  scoped_ptr<jingle_glue::TaskPump> task_pump_;
66  MockXmppDelegate mock_xmpp_delegate_;
67};
68
69TEST_F(WeakXmppClientTest, InvalidationViaInvalidate) {
70  ExpectSignalCalls();
71
72  WeakXmppClient* weak_xmpp_client = new WeakXmppClient(task_pump_.get());
73  ConnectSignals(weak_xmpp_client);
74
75  weak_xmpp_client->Start();
76  base::WeakPtr<WeakXmppClient> weak_ptr = weak_xmpp_client->AsWeakPtr();
77  EXPECT_TRUE(weak_ptr.get());
78  RaiseSignals(weak_ptr.get());
79
80  weak_xmpp_client->Invalidate();
81  EXPECT_FALSE(weak_ptr.get());
82  // We know that |weak_xmpp_client| is still valid at this point,
83  // although it should be entirely disconnected.
84  RaiseSignals(weak_xmpp_client);
85}
86
87TEST_F(WeakXmppClientTest, InvalidationViaStop) {
88  ExpectSignalCalls();
89
90  WeakXmppClient* weak_xmpp_client = new WeakXmppClient(task_pump_.get());
91  ConnectSignals(weak_xmpp_client);
92
93  weak_xmpp_client->Start();
94  base::WeakPtr<WeakXmppClient> weak_ptr = weak_xmpp_client->AsWeakPtr();
95  EXPECT_TRUE(weak_ptr.get());
96  RaiseSignals(weak_ptr.get());
97
98  weak_xmpp_client->Abort();
99  EXPECT_FALSE(weak_ptr.get());
100  // We know that |weak_xmpp_client| is still valid at this point,
101  // although it should be entirely disconnected.
102  RaiseSignals(weak_xmpp_client);
103}
104
105TEST_F(WeakXmppClientTest, InvalidationViaDestructor) {
106  ExpectSignalCalls();
107
108  WeakXmppClient* weak_xmpp_client = new WeakXmppClient(task_pump_.get());
109  ConnectSignals(weak_xmpp_client);
110
111  weak_xmpp_client->Start();
112  base::WeakPtr<WeakXmppClient> weak_ptr = weak_xmpp_client->AsWeakPtr();
113  EXPECT_TRUE(weak_ptr.get());
114  RaiseSignals(weak_ptr.get());
115
116  task_pump_.reset();
117  EXPECT_FALSE(weak_ptr.get());
118  // |weak_xmpp_client| is truly invalid at this point so we can't
119  // RaiseSignals() with it.
120}
121
122}  // namespace
123
124}  // namespace notifier
125