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_.get(), OnSendTo(_)) 145 .Times(AtLeast(2)); 146 } 147 148 protected: 149 base::MessageLoop message_loop_; 150 scoped_refptr<TestServiceDiscoveryClient> test_service_discovery_client_; 151 scoped_refptr<net::TestURLRequestContextGetter> url_request_context_; 152 scoped_ptr<PrivetLocalPrinterLister> local_printer_lister_; 153 net::TestURLFetcherFactory fetcher_factory_; 154 StrictMock<MockLocalPrinterListerDelegate> delegate_; 155}; 156 157TEST_F(PrivetLocalPrinterListerTest, PrinterAddedTest) { 158 ExpectAnyPacket(); 159 160 local_printer_lister_->Start(); 161 162 SimulateReceive(kAnnouncePacket, sizeof(kAnnouncePacket)); 163 164 EXPECT_CALL(delegate_, LocalPrinterChanged(true, kServiceName, true, _)); 165 166 EXPECT_TRUE(SuccessfulResponseToURL( 167 GURL(kPrivetInfoURL), 168 std::string(kInfoIsLocalPrinter))); 169}; 170 171TEST_F(PrivetLocalPrinterListerTest, NonPrinterAddedTest) { 172 ExpectAnyPacket(); 173 174 local_printer_lister_->Start(); 175 176 SimulateReceive(kAnnouncePacket, sizeof(kAnnouncePacket)); 177 178 EXPECT_CALL(delegate_, LocalPrinterChanged(true, kServiceName, false, _)); 179 180 EXPECT_TRUE(SuccessfulResponseToURL( 181 GURL(kPrivetInfoURL), 182 std::string(kInfoIsNotLocalPrinter))); 183}; 184 185} // namespace 186 187} // namespace local_discovery 188