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