1 // Copyright (c) 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 "chrome/service/cloud_print/printer_job_queue_handler.h" 6 7 #include <set> 8 9 #include "base/json/json_reader.h" 10 #include "base/values.h" 11 #include "testing/gmock/include/gmock/gmock.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 14 using ::testing::Return; 15 using ::testing::AtLeast; 16 17 namespace cloud_print { 18 19 const char kJobListResponse[] = 20 "{" 21 " \"success\" : true, " 22 " \"jobs\" : [" 23 "{" 24 " \"tags\" : [ \"^own\", \"\"], " 25 " \"title\" : \"test1\"," 26 " \"ticketUrl\" : \"http://example.com/job1ticket\"," 27 " \"fileUrl\" : \"http://example.com/job1data\"," 28 " \"id\" : \"__testjob1\"" 29 "}," 30 "{" 31 " \"tags\" : [ \"^own\", \"\"], " 32 " \"title\" : \"test2\"," 33 " \"ticketUrl\" : \"http://example.com/job2ticket\"," 34 " \"fileUrl\" : \"http://example.com/job2data\"," 35 " \"id\" : \"__testjob2\"" 36 "}," 37 "{" 38 " \"tags\" : [ \"^own\", \"\"], " 39 " \"title\" : \"test3\"," 40 " \"ticketUrl\" : \"http://example.com/job3ticket\"," 41 " \"fileUrl\" : \"http://example.com/job3data\"," 42 " \"id\" : \"__testjob3\"" 43 "}" 44 "]" 45 "}"; 46 47 class TimeProviderMock : public PrinterJobQueueHandler::TimeProvider { 48 public: 49 MOCK_METHOD0(GetNow, base::Time()); 50 }; 51 52 class PrinterJobQueueHandlerTest : public ::testing::Test { 53 protected: 54 Value* data_; 55 DictionaryValue* json_data_; 56 virtual void SetUp() { 57 base::JSONReader json_reader; 58 data_ = json_reader.Read(kJobListResponse); 59 data_->GetAsDictionary(&json_data_); 60 } 61 62 virtual void TearDown() { 63 delete data_; 64 } 65 }; 66 67 TEST_F(PrinterJobQueueHandlerTest, BasicJobReadTest) { 68 PrinterJobQueueHandler job_queue_handler; 69 std::vector<JobDetails> jobs; 70 71 job_queue_handler.GetJobsFromQueue(json_data_, &jobs); 72 73 ASSERT_EQ((size_t)3, jobs.size()); 74 75 EXPECT_EQ(std::string("__testjob1"), jobs[0].job_id_); 76 EXPECT_EQ(std::string("test1"), jobs[0].job_title_); 77 EXPECT_EQ(std::string("http://example.com/job1ticket"), 78 jobs[0].print_ticket_url_); 79 EXPECT_EQ(std::string("http://example.com/job1data"), 80 jobs[0].print_data_url_); 81 82 std::set<std::string> expected_tags; 83 expected_tags.insert("^own"); 84 expected_tags.insert(std::string()); 85 std::set<std::string> actual_tags; 86 actual_tags.insert(jobs[0].tags_.begin(), jobs[0].tags_.end()); 87 88 EXPECT_EQ(expected_tags, actual_tags); 89 EXPECT_EQ(base::TimeDelta(), jobs[0].time_remaining_); 90 } 91 92 TEST_F(PrinterJobQueueHandlerTest, PreferNonFailureTest) { 93 TimeProviderMock* time_mock = new TimeProviderMock(); 94 PrinterJobQueueHandler job_queue_handler(time_mock); 95 EXPECT_CALL((*time_mock), GetNow()) 96 .Times(AtLeast(2)) 97 .WillRepeatedly(Return(base::Time::UnixEpoch())); 98 99 // must fail twice for backoff to kick in 100 job_queue_handler.JobFetchFailed("__testjob1"); 101 job_queue_handler.JobFetchFailed("__testjob1"); 102 103 std::vector<JobDetails> jobs; 104 job_queue_handler.GetJobsFromQueue(json_data_, &jobs); 105 106 EXPECT_EQ(std::string("__testjob2"), jobs[0].job_id_); 107 EXPECT_EQ(base::TimeDelta(), jobs[0].time_remaining_); 108 } 109 110 TEST_F(PrinterJobQueueHandlerTest, PreferNoTimeTest) { 111 TimeProviderMock* time_mock = new TimeProviderMock(); 112 PrinterJobQueueHandler job_queue_handler(time_mock); 113 EXPECT_CALL((*time_mock), GetNow()). 114 Times(AtLeast(8)); 115 116 ON_CALL((*time_mock), GetNow()) 117 .WillByDefault(Return(base::Time::UnixEpoch())); 118 119 for (int i = 0; i < 4; i++) 120 job_queue_handler.JobFetchFailed("__testjob1"); 121 122 ON_CALL((*time_mock), GetNow()) 123 .WillByDefault(Return(base::Time::UnixEpoch() + 124 base::TimeDelta::FromMinutes(4))); 125 126 for (int i = 0; i < 2; i++) 127 job_queue_handler.JobFetchFailed("__testjob2"); 128 129 for (int i = 0; i < 2; i++) 130 job_queue_handler.JobFetchFailed("__testjob3"); 131 132 std::vector<JobDetails> jobs; 133 job_queue_handler.GetJobsFromQueue(json_data_, &jobs); 134 135 EXPECT_EQ(base::TimeDelta(), jobs[0].time_remaining_); 136 EXPECT_EQ(std::string("__testjob1"), jobs[0].job_id_); 137 } 138 139 TEST_F(PrinterJobQueueHandlerTest, PreferLowerTimeTest) { 140 TimeProviderMock* time_mock = new TimeProviderMock(); 141 PrinterJobQueueHandler job_queue_handler(time_mock); 142 143 EXPECT_CALL((*time_mock), GetNow()). 144 Times(AtLeast(8)); 145 146 ON_CALL((*time_mock), GetNow()) 147 .WillByDefault(Return(base::Time::UnixEpoch())); 148 149 for (int i = 0; i < 4; i++) 150 job_queue_handler.JobFetchFailed("__testjob1"); 151 152 ON_CALL((*time_mock), GetNow()) 153 .WillByDefault(Return(base::Time::UnixEpoch() + 154 base::TimeDelta::FromSeconds(4))); 155 156 for (int i = 0; i < 2; i++) 157 job_queue_handler.JobFetchFailed("__testjob2"); 158 159 for (int i = 0; i < 2; i++) 160 job_queue_handler.JobFetchFailed("__testjob3"); 161 162 std::vector<JobDetails> jobs; 163 job_queue_handler.GetJobsFromQueue(json_data_, 164 &jobs); 165 166 base::TimeDelta time_to_wait = jobs[0].time_remaining_; 167 EXPECT_NE(base::TimeDelta(), time_to_wait); 168 169 jobs.clear(); 170 ON_CALL((*time_mock), GetNow()) 171 .WillByDefault(Return(base::Time::UnixEpoch() + 172 base::TimeDelta::FromSeconds(4) + time_to_wait)); 173 174 job_queue_handler.GetJobsFromQueue(json_data_, 175 &jobs); 176 177 EXPECT_EQ(base::TimeDelta(), jobs[0].time_remaining_); 178 EXPECT_EQ(std::string("__testjob2"), jobs[0].job_id_); 179 } 180 181 } // namespace cloud_print 182