privet_local_printer_lister_unittest.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1// Copyright 2013 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 "base/message_loop/message_loop.h"
6#include "chrome/browser/local_discovery/privet_local_printer_lister.h"
7#include "chrome/browser/local_discovery/test_service_discovery_client.h"
8#include "net/url_request/test_url_fetcher_factory.h"
9#include "net/url_request/url_request_test_util.h"
10
11#include "testing/gmock/include/gmock/gmock.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14using testing::StrictMock;
15using testing::_;
16
17namespace local_discovery {
18
19namespace {
20
21const uint8 kAnnouncePacket[] = {
22  // Header
23  0x00, 0x00,               // ID is zeroed out
24  0x80, 0x00,               // Standard query response, no error
25  0x00, 0x00,               // No questions (for simplicity)
26  0x00, 0x05,               // 5 RR (answers)
27  0x00, 0x00,               // 0 authority RRs
28  0x00, 0x00,               // 0 additional RRs
29
30  0x08, '_', 'p', 'r', 'i', 'n', 't', 'e', 'r',
31  0x04, '_', 's', 'u', 'b',
32  0x07, '_', 'p', 'r', 'i', 'v', 'e', 't',
33  0x04, '_', 't', 'c', 'p',
34  0x05, 'l', 'o', 'c', 'a', 'l',
35  0x00,
36  0x00, 0x0c,        // TYPE is PTR.
37  0x00, 0x01,        // CLASS is IN.
38  0x00, 0x00,        // TTL (4 bytes) is 32768 second.
39  0x10, 0x00,
40  0x00, 0x0c,        // RDLENGTH is 12 bytes.
41  0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
42  0xc0, 0x0c,
43
44  0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
45  0xc0, 0x0c,
46  0x00, 0x10,        // TYPE is TXT.
47  0x00, 0x01,        // CLASS is IN.
48  0x00, 0x00,        // TTL (4 bytes) is 32768 seconds.
49  0x01, 0x00,
50  0x00, 0x37,        // RDLENGTH is 55 bytes.
51  0x06, 'i', 'd', '=', 'r', 'e', 'g',
52  0x10, 't', 'y', '=', 'S', 'a', 'm', 'p', 'l', 'e', ' ',
53        'd', 'e', 'v', 'i', 'c', 'e',
54  0x1e, 'n', 'o', 't', 'e', '=',
55        'S', 'a', 'm', 'p', 'l', 'e', ' ', 'd', 'e', 'v', 'i', 'c', 'e', ' ',
56        'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n',
57
58  0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
59  0xc0, 0x0c,
60  0x00, 0x21,        // Type is SRV
61  0x00, 0x01,        // CLASS is IN
62  0x00, 0x00,        // TTL (4 bytes) is 32768 second.
63  0x10, 0x00,
64  0x00, 0x17,        // RDLENGTH is 23
65  0x00, 0x00,
66  0x00, 0x00,
67  0x22, 0xb8,        // port 8888
68  0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
69  0x05, 'l', 'o', 'c', 'a', 'l',
70  0x00,
71
72  0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
73  0x05, 'l', 'o', 'c', 'a', 'l',
74  0x00,
75  0x00, 0x01,        // Type is A
76  0x00, 0x01,        // CLASS is IN
77  0x00, 0x00,        // TTL (4 bytes) is 32768 second.
78  0x10, 0x00,
79  0x00, 0x04,        // RDLENGTH is 4
80  0x01, 0x02, 0x03, 0x04,  // 1.2.3.4
81
82  0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e',
83  0x05, 'l', 'o', 'c', 'a', 'l',
84  0x00,
85  0x00, 0x1C,        // Type is AAAA
86  0x00, 0x01,        // CLASS is IN
87  0x00, 0x00,        // TTL (4 bytes) is 32768 second.
88  0x10, 0x00,
89  0x00, 0x10,        // RDLENGTH is 16
90  0x01, 0x02, 0x03, 0x04,  // 1.2.3.4
91  0x01, 0x02, 0x03, 0x04,
92  0x01, 0x02, 0x03, 0x04,
93  0x01, 0x02, 0x03, 0x04,
94};
95
96const char kInfoIsLocalPrinter[] = "{"
97    "\"api\" : [ \"/privet/printer/submitdoc\" ],"
98    "\"x-privet-token\" : \"sample\""
99    "}";
100
101const char kInfoIsNotLocalPrinter[] = "{"
102    "\"api\" : [ \"/privet/register\" ],"
103    "\"x-privet-token\" : \"sample\""
104    "}";
105
106const char kServiceName[] = "myService._printer._sub._privet._tcp.local";
107
108const char kPrivetInfoURL[] = "http://1.2.3.4:8888/privet/info";
109
110class MockLocalPrinterListerDelegate
111    : public PrivetLocalPrinterLister::Delegate {
112 public:
113  MockLocalPrinterListerDelegate() {
114  }
115
116  virtual ~MockLocalPrinterListerDelegate() {
117  }
118
119  MOCK_METHOD4(LocalPrinterChanged, void(bool added,
120                                         const std::string& name,
121                                         bool has_local_printing,
122                                         const DeviceDescription& description));
123
124  MOCK_METHOD1(LocalPrinterRemoved, void(const std::string& name));
125
126  MOCK_METHOD0(LocalPrinterCacheFlushed, void());
127};
128
129class PrivetLocalPrinterListerTest : public testing::Test {
130 public:
131  PrivetLocalPrinterListerTest() {
132    test_service_discovery_client_ = new TestServiceDiscoveryClient();
133    test_service_discovery_client_->Start();
134    url_request_context_ = new net::TestURLRequestContextGetter(
135        base::MessageLoopProxy::current());
136    local_printer_lister_.reset(new PrivetLocalPrinterLister(
137        test_service_discovery_client_.get(),
138        url_request_context_.get(),
139        &delegate_));
140  }
141
142  ~PrivetLocalPrinterListerTest() {
143  }
144
145  bool SuccessfulResponseToURL(const GURL& url,
146                               const std::string& response) {
147    net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
148    EXPECT_TRUE(fetcher);
149    EXPECT_EQ(url, fetcher->GetOriginalURL());
150
151    if (!fetcher || url != fetcher->GetOriginalURL())
152      return false;
153
154    fetcher->SetResponseString(response);
155    fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
156                                              net::OK));
157    fetcher->set_response_code(200);
158    fetcher->delegate()->OnURLFetchComplete(fetcher);
159    return true;
160  }
161
162  void SimulateReceive(const uint8* packet, size_t size) {
163    test_service_discovery_client_->SimulateReceive(packet, size);
164    message_loop_.RunUntilIdle();
165  }
166
167  void ExpectAnyPacket() {
168    EXPECT_CALL(*test_service_discovery_client_, OnSendTo(_))
169        .Times(2);
170  }
171
172 protected:
173  base::MessageLoop message_loop_;
174  scoped_refptr<TestServiceDiscoveryClient> test_service_discovery_client_;
175  scoped_refptr<net::TestURLRequestContextGetter> url_request_context_;
176  scoped_ptr<PrivetLocalPrinterLister> local_printer_lister_;
177  net::TestURLFetcherFactory fetcher_factory_;
178  StrictMock<MockLocalPrinterListerDelegate> delegate_;
179};
180
181TEST_F(PrivetLocalPrinterListerTest, PrinterAddedTest) {
182  ExpectAnyPacket();
183
184  local_printer_lister_->Start();
185
186  SimulateReceive(kAnnouncePacket, sizeof(kAnnouncePacket));
187
188  EXPECT_CALL(delegate_, LocalPrinterChanged(true, kServiceName, true, _));
189
190  EXPECT_TRUE(SuccessfulResponseToURL(
191      GURL(kPrivetInfoURL),
192      std::string(kInfoIsLocalPrinter)));
193};
194
195TEST_F(PrivetLocalPrinterListerTest, NonPrinterAddedTest) {
196  ExpectAnyPacket();
197
198  local_printer_lister_->Start();
199
200  SimulateReceive(kAnnouncePacket, sizeof(kAnnouncePacket));
201
202  EXPECT_CALL(delegate_, LocalPrinterChanged(true, kServiceName, false, _));
203
204  EXPECT_TRUE(SuccessfulResponseToURL(
205      GURL(kPrivetInfoURL),
206      std::string(kInfoIsNotLocalPrinter)));
207};
208
209}  // namespace
210
211}  // namespace local_discovery
212