12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/service/cloud_print/printer_job_queue_handler.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <set>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_reader.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::Return;
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::AtLeast;
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cloud_print {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kJobListResponse[] =
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "{"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    " \"success\" : true, "
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    " \"jobs\" : ["
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "{"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  \"tags\" : [ \"^own\", \"\"], "
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  \"title\" : \"test1\","
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  \"ticketUrl\" : \"http://example.com/job1ticket\","
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  \"fileUrl\" : \"http://example.com/job1data\","
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  \"id\" : \"__testjob1\""
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "},"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "{"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  \"tags\" : [ \"^own\", \"\"], "
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  \"title\" : \"test2\","
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  \"ticketUrl\" : \"http://example.com/job2ticket\","
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  \"fileUrl\" : \"http://example.com/job2data\","
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  \"id\" : \"__testjob2\""
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "},"
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "{"
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  \"tags\" : [ \"^own\", \"\"], "
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  \"title\" : \"test3\","
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  \"ticketUrl\" : \"http://example.com/job3ticket\","
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  \"fileUrl\" : \"http://example.com/job3data\","
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "  \"id\" : \"__testjob3\""
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "}"
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "]"
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "}";
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TimeProviderMock : public PrinterJobQueueHandler::TimeProvider {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD0(GetNow, base::Time());
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PrinterJobQueueHandlerTest : public ::testing::Test {
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::Value* data_;
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue* json_data_;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::JSONReader json_reader;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data_ = json_reader.Read(kJobListResponse);
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data_->GetAsDictionary(&json_data_);
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown() {
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete data_;
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(PrinterJobQueueHandlerTest, BasicJobReadTest) {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrinterJobQueueHandler job_queue_handler;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<JobDetails> jobs;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job_queue_handler.GetJobsFromQueue(json_data_, &jobs);
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ((size_t)3, jobs.size());
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(std::string("__testjob1"), jobs[0].job_id_);
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(std::string("test1"), jobs[0].job_title_);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(std::string("http://example.com/job1ticket"),
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            jobs[0].print_ticket_url_);
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(std::string("http://example.com/job1data"),
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            jobs[0].print_data_url_);
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<std::string> expected_tags;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected_tags.insert("^own");
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  expected_tags.insert(std::string());
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<std::string> actual_tags;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  actual_tags.insert(jobs[0].tags_.begin(), jobs[0].tags_.end());
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(expected_tags, actual_tags);
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::TimeDelta(), jobs[0].time_remaining_);
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(PrinterJobQueueHandlerTest, PreferNonFailureTest) {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TimeProviderMock* time_mock = new TimeProviderMock();
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrinterJobQueueHandler job_queue_handler(time_mock);
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL((*time_mock), GetNow())
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Times(AtLeast(2))
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillRepeatedly(Return(base::Time::UnixEpoch()));
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // must fail twice for backoff to kick in
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job_queue_handler.JobFetchFailed("__testjob1");
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job_queue_handler.JobFetchFailed("__testjob1");
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<JobDetails> jobs;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job_queue_handler.GetJobsFromQueue(json_data_, &jobs);
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(std::string("__testjob2"), jobs[0].job_id_);
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::TimeDelta(), jobs[0].time_remaining_);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(PrinterJobQueueHandlerTest, PreferNoTimeTest) {
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TimeProviderMock* time_mock = new TimeProviderMock();
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrinterJobQueueHandler job_queue_handler(time_mock);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL((*time_mock), GetNow()).
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Times(AtLeast(8));
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ON_CALL((*time_mock), GetNow())
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillByDefault(Return(base::Time::UnixEpoch()));
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 4; i++)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    job_queue_handler.JobFetchFailed("__testjob1");
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ON_CALL((*time_mock), GetNow())
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillByDefault(Return(base::Time::UnixEpoch() +
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            base::TimeDelta::FromMinutes(4)));
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; i++)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    job_queue_handler.JobFetchFailed("__testjob2");
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; i++)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    job_queue_handler.JobFetchFailed("__testjob3");
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<JobDetails> jobs;
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job_queue_handler.GetJobsFromQueue(json_data_, &jobs);
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::TimeDelta(), jobs[0].time_remaining_);
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(std::string("__testjob1"), jobs[0].job_id_);
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(PrinterJobQueueHandlerTest, PreferLowerTimeTest) {
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TimeProviderMock* time_mock = new TimeProviderMock();
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrinterJobQueueHandler job_queue_handler(time_mock);
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL((*time_mock), GetNow()).
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Times(AtLeast(8));
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ON_CALL((*time_mock), GetNow())
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillByDefault(Return(base::Time::UnixEpoch()));
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 4; i++)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    job_queue_handler.JobFetchFailed("__testjob1");
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ON_CALL((*time_mock), GetNow())
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillByDefault(Return(base::Time::UnixEpoch() +
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            base::TimeDelta::FromSeconds(4)));
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; i++)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    job_queue_handler.JobFetchFailed("__testjob2");
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; i++)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    job_queue_handler.JobFetchFailed("__testjob3");
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<JobDetails> jobs;
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job_queue_handler.GetJobsFromQueue(json_data_,
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                   &jobs);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta time_to_wait = jobs[0].time_remaining_;
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(base::TimeDelta(), time_to_wait);
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  jobs.clear();
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ON_CALL((*time_mock), GetNow())
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillByDefault(Return(base::Time::UnixEpoch() +
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            base::TimeDelta::FromSeconds(4) + time_to_wait));
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job_queue_handler.GetJobsFromQueue(json_data_,
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     &jobs);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::TimeDelta(), jobs[0].time_remaining_);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(std::string("__testjob2"),  jobs[0].job_id_);
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cloud_print
182