cloudprint 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.gitignore +1 -0
- data/.travis.yml +5 -0
- data/README.md +121 -0
- data/Rakefile +3 -1
- data/cloudprint.gemspec +2 -2
- data/lib/cloudprint.rb +4 -71
- data/lib/cloudprint/client.rb +48 -0
- data/lib/cloudprint/connection.rb +7 -3
- data/lib/cloudprint/exceptions.rb +6 -0
- data/lib/cloudprint/print_job.rb +44 -38
- data/lib/cloudprint/print_job_collection.rb +39 -0
- data/lib/cloudprint/printer.rb +15 -19
- data/lib/cloudprint/printer_collection.rb +52 -0
- data/lib/cloudprint/version.rb +1 -1
- data/test/cloudprint_test.rb +47 -51
- data/test/connection_test.rb +2 -2
- data/test/helper.rb +7 -3
- data/test/print_job_test.rb +65 -13
- data/test/printer_test.rb +82 -17
- metadata +17 -33
- data/Gemfile.lock +0 -38
- data/README.rdoc +0 -19
data/lib/cloudprint/printer.rb
CHANGED
@@ -1,37 +1,33 @@
|
|
1
1
|
module CloudPrint
|
2
2
|
class Printer
|
3
|
-
|
3
|
+
CONNECTION_STATUSES = %w{ONLINE UNKNOWN OFFLINE DORMANT}
|
4
|
+
CONFIG_OPTS = [:id, :status, :name, :tags, :display_name, :client, :connection_status, :description]
|
5
|
+
|
6
|
+
attr_reader *CONFIG_OPTS
|
7
|
+
|
4
8
|
def initialize(options = {})
|
9
|
+
@client = options[:client]
|
5
10
|
@id = options[:id]
|
6
11
|
@status = options[:status]
|
7
12
|
@name = options[:name]
|
8
13
|
@display_name = options[:display_name]
|
9
14
|
@tags = options[:tags] || {}
|
15
|
+
@connection_status = options[:connection_status] || 'UNKNOWN'
|
16
|
+
@description = options[:description]
|
10
17
|
end
|
11
18
|
|
12
19
|
def print(options)
|
13
20
|
method = options[:content].is_a?(IO) ? :multipart_post : :post
|
14
|
-
response =
|
21
|
+
response = client.connection.send(method, '/submit', :printerid => self.id, :title => options[:title], :content => options[:content], :contentType => options[:content_type]) || {}
|
15
22
|
return nil if response.nil? || response["job"].nil?
|
16
|
-
|
23
|
+
client.print_jobs.new_from_response response["job"]
|
17
24
|
end
|
18
25
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
def all
|
27
|
-
response = CloudPrint.connection.get('/search')
|
28
|
-
response['printers'].map { |p| new_from_hash(p) }
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def new_from_hash(hash)
|
34
|
-
Printer.new(:id => hash['id'], :status => hash['status'], :name => hash['name'], :display_name => hash['displayName'], :tags => hash['tags'])
|
26
|
+
def method_missing(meth, *args, &block)
|
27
|
+
if CONNECTION_STATUSES.map{ |s| s.downcase + '?' }.include?(meth.to_s)
|
28
|
+
connection_status.downcase == meth.to_s.chop
|
29
|
+
else
|
30
|
+
super
|
35
31
|
end
|
36
32
|
end
|
37
33
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module CloudPrint
|
2
|
+
class PrinterCollection
|
3
|
+
|
4
|
+
attr_reader :client
|
5
|
+
|
6
|
+
def initialize client
|
7
|
+
@client = client
|
8
|
+
end
|
9
|
+
|
10
|
+
def find(printer_id)
|
11
|
+
response = client.connection.get('/printer', :printerid => printer_id, :printer_connection_status => true)
|
12
|
+
first_printer_hash = response['printers'].first
|
13
|
+
new_printer_from_hash(first_printer_hash)
|
14
|
+
end
|
15
|
+
|
16
|
+
def all
|
17
|
+
search_all
|
18
|
+
end
|
19
|
+
|
20
|
+
def search(query = nil, conditions = {})
|
21
|
+
conditions[:q] = query unless query.nil?
|
22
|
+
|
23
|
+
response = client.connection.get('/search', conditions)
|
24
|
+
response['printers'].map { |p| new_printer_from_hash(p) }
|
25
|
+
end
|
26
|
+
|
27
|
+
def method_missing(meth, *args, &block)
|
28
|
+
if meth =~ /^search_(#{Printer::CONNECTION_STATUSES.map(&:downcase).join('|')}|all)$/
|
29
|
+
search args[0], connection_status: $1.upcase
|
30
|
+
else
|
31
|
+
super
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def new opts
|
36
|
+
Printer.new(opts.merge(client: client))
|
37
|
+
end
|
38
|
+
|
39
|
+
def new_printer_from_hash(hash)
|
40
|
+
Printer.new(
|
41
|
+
client: client,
|
42
|
+
id: hash['id'],
|
43
|
+
status: hash['status'],
|
44
|
+
name: hash['name'],
|
45
|
+
display_name: hash['displayName'],
|
46
|
+
tags: hash['tags'],
|
47
|
+
connection_status: hash['connectionStatus'],
|
48
|
+
description: hash['description']
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/cloudprint/version.rb
CHANGED
data/test/cloudprint_test.rb
CHANGED
@@ -3,6 +3,7 @@ require 'helper'
|
|
3
3
|
class CloudPrintTest < Test::Unit::TestCase
|
4
4
|
def setup
|
5
5
|
stub_access_token
|
6
|
+
@client = new_client
|
6
7
|
end
|
7
8
|
|
8
9
|
should "have CloudPrint" do
|
@@ -10,113 +11,108 @@ class CloudPrintTest < Test::Unit::TestCase
|
|
10
11
|
end
|
11
12
|
|
12
13
|
should "be able to set up CloudPrint" do
|
13
|
-
|
14
|
-
|
14
|
+
assert_nothing_raised do
|
15
|
+
CloudPrint::Client.new
|
16
|
+
end
|
17
|
+
end
|
15
18
|
|
16
19
|
should "stores a client id, client secret, callback URL and refresh token" do
|
17
|
-
CloudPrint.
|
18
|
-
assert_equal 'client_id',
|
19
|
-
assert_equal 'client_secret',
|
20
|
-
assert_equal 'refresh_token',
|
21
|
-
assert_equal 'callback_url',
|
20
|
+
client = CloudPrint::Client.new(:refresh_token => 'refresh_token', :client_id => 'client_id', :client_secret => 'client_secret', :callback_url => 'callback_url')
|
21
|
+
assert_equal 'client_id', client.client_id
|
22
|
+
assert_equal 'client_secret', client.client_secret
|
23
|
+
assert_equal 'refresh_token', client.refresh_token
|
24
|
+
assert_equal 'callback_url', client.callback_url
|
22
25
|
end
|
23
26
|
|
24
27
|
should "check if the access token is still valid" do
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
+
@client.expects(:access_token_valid?).returns(true)
|
29
|
+
@client.stubs(:renew_access_token!).returns(mock_access_token)
|
30
|
+
@client.access_token
|
28
31
|
end
|
29
32
|
|
30
33
|
should "get the existing access token use it if it's still valid" do
|
31
34
|
token = mock_access_token
|
32
35
|
token.expects(:token)
|
33
36
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
37
|
+
@client.stubs(:access_token_valid?).returns(true)
|
38
|
+
@client.instance_variable_set :@access_token, token
|
39
|
+
@client.expects(:renew_access_token!).never
|
40
|
+
@client.access_token
|
38
41
|
end
|
39
42
|
|
40
43
|
should "get the existing access token get a new one if it's no longer valid" do
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
should "not set a nil access token" do
|
47
|
-
CloudPrint.expects(:get_existing_access_token).returns(nil)
|
48
|
-
CloudPrint.expects(:get_new_access_token).returns(mock_access_token)
|
49
|
-
CloudPrint.access_token
|
44
|
+
@client.stubs(:access_token_valid?).returns(false)
|
45
|
+
@client.expects(:renew_access_token!).returns(mock_access_token)
|
46
|
+
@client.access_token
|
50
47
|
end
|
51
48
|
|
52
49
|
should "not have a nil access token" do
|
53
|
-
|
54
|
-
|
55
|
-
|
50
|
+
@client.instance_variable_set :@access_token, nil
|
51
|
+
@client.expects(:renew_access_token!).returns(mock_access_token)
|
52
|
+
@client.access_token
|
56
53
|
end
|
57
54
|
|
58
55
|
should "not allow a blank string for an access token" do
|
59
|
-
|
60
|
-
|
61
|
-
|
56
|
+
@client.instance_variable_set :@access_token, ' '
|
57
|
+
@client.expects(:renew_access_token!).returns(mock_access_token)
|
58
|
+
@client.access_token
|
62
59
|
end
|
63
60
|
|
64
61
|
should "have a string as an access token" do
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
assert_equal("token",
|
62
|
+
@client.stubs(:access_token_valid?).returns(true)
|
63
|
+
@client.expects(:renew_access_token!).never
|
64
|
+
@client.instance_variable_set :@access_token, mock_access_token
|
65
|
+
assert_equal("token", @client.access_token)
|
69
66
|
end
|
70
67
|
|
71
68
|
should "initialize an OAuth2 client when getting a new access token" do
|
72
|
-
|
73
|
-
|
74
|
-
|
69
|
+
@client.stubs(:access_token_valid?).returns(false)
|
70
|
+
@client.expects(:oauth_client)
|
71
|
+
@client.access_token
|
75
72
|
end
|
76
73
|
|
77
74
|
should "set up an oauth client" do
|
78
|
-
CloudPrint.
|
79
|
-
|
75
|
+
client = CloudPrint::Client.new(:client_id => 'client_id', :client_secret => 'client_secret', :callback_url => "http://test.com/callback")
|
76
|
+
client.stubs(:access_token_valid?).returns(false)
|
80
77
|
OAuth2::Client.expects(:new).with('client_id', 'client_secret',
|
81
78
|
:authorize_url => "/o/oauth2/auth",
|
82
79
|
:token_url => "/o/oauth2/token",
|
83
80
|
:access_token_url => "/o/oauth2/token",
|
84
81
|
:site => 'https://accounts.google.com/')
|
85
82
|
|
86
|
-
|
83
|
+
client.access_token
|
87
84
|
end
|
88
85
|
|
89
86
|
should "initialize an access token when getting a new access token" do
|
90
|
-
CloudPrint.
|
91
|
-
|
87
|
+
client = CloudPrint::Client.new(:refresh_token => "refresh_token")
|
88
|
+
client.stubs(:access_token_valid?).returns(false)
|
92
89
|
|
93
|
-
|
94
|
-
|
90
|
+
client.expects(:renew_access_token!).returns(mock_access_token)
|
91
|
+
client.access_token
|
95
92
|
end
|
96
93
|
|
97
94
|
should "get an auth token from oauth2" do
|
98
95
|
token = mock_access_token
|
99
|
-
|
100
|
-
CloudPrint.stubs(:access_token_valid?).returns(false)
|
96
|
+
@client.stubs(:access_token_valid?).returns(false)
|
101
97
|
stub_oauth_client
|
102
98
|
|
103
99
|
OAuth2::AccessToken.expects(:new).with(mock_oauth_client, "", :refresh_token => "refresh_token").returns(token)
|
104
100
|
token.expects(:refresh!).returns(mock_access_token)
|
105
|
-
|
101
|
+
@client.access_token
|
106
102
|
end
|
107
103
|
|
108
104
|
should "expire if the access token is invalid" do
|
109
105
|
token = mock_access_token
|
110
106
|
token.stubs(:expired?).returns(true)
|
111
|
-
|
107
|
+
@client.instance_variable_set :@access_token, token
|
112
108
|
stub_oauth_client
|
113
109
|
|
114
|
-
|
115
|
-
|
110
|
+
@client.expects(:renew_access_token!).returns(token)
|
111
|
+
@client.access_token
|
116
112
|
end
|
117
113
|
|
118
114
|
should "get a new access token when setting a new refresh token" do
|
119
|
-
|
120
|
-
|
115
|
+
@client.expects(:renew_access_token!)
|
116
|
+
@client.refresh_token = 'new_token'
|
121
117
|
end
|
122
118
|
end
|
data/test/connection_test.rb
CHANGED
@@ -2,7 +2,8 @@ require "helper"
|
|
2
2
|
|
3
3
|
class ConnectionTest < Test::Unit::TestCase
|
4
4
|
def setup
|
5
|
-
|
5
|
+
stub_access_token
|
6
|
+
@connection = new_client.connection
|
6
7
|
end
|
7
8
|
|
8
9
|
should "get using a connection" do
|
@@ -66,7 +67,6 @@ class ConnectionTest < Test::Unit::TestCase
|
|
66
67
|
stub
|
67
68
|
@connection.stubs(:build_http_connection).returns(mock_http)
|
68
69
|
|
69
|
-
CloudPrint.expects(:access_token).returns('token')
|
70
70
|
@connection.get('/submit')
|
71
71
|
end
|
72
72
|
|
data/test/helper.rb
CHANGED
@@ -4,6 +4,11 @@ require 'shoulda/context'
|
|
4
4
|
require 'mocha'
|
5
5
|
|
6
6
|
class Test::Unit::TestCase
|
7
|
+
|
8
|
+
def new_client
|
9
|
+
CloudPrint::Client.new(refresh_token: "refresh_token")
|
10
|
+
end
|
11
|
+
|
7
12
|
def any_connection
|
8
13
|
CloudPrint::Connection.any_instance
|
9
14
|
end
|
@@ -26,7 +31,6 @@ class Test::Unit::TestCase
|
|
26
31
|
|
27
32
|
def stub_http
|
28
33
|
mock = mock_http()
|
29
|
-
|
30
34
|
Net::HTTP.stubs(:new).returns(mock)
|
31
35
|
end
|
32
36
|
|
@@ -45,7 +49,7 @@ class Test::Unit::TestCase
|
|
45
49
|
end
|
46
50
|
|
47
51
|
def stub_oauth_client
|
48
|
-
CloudPrint.stubs(:oauth_client).returns(mock_oauth_client)
|
52
|
+
CloudPrint::Client.any_instance.stubs(:oauth_client).returns(mock_oauth_client)
|
49
53
|
end
|
50
54
|
|
51
55
|
def fake_connection
|
@@ -53,7 +57,7 @@ class Test::Unit::TestCase
|
|
53
57
|
end
|
54
58
|
|
55
59
|
def stub_connection
|
56
|
-
CloudPrint.stubs(:connection).returns(fake_connection)
|
60
|
+
CloudPrint::Client.any_instance.stubs(:connection).returns(fake_connection)
|
57
61
|
@connection.stub_everything
|
58
62
|
end
|
59
63
|
|
data/test/print_job_test.rb
CHANGED
@@ -3,32 +3,41 @@ require 'helper'
|
|
3
3
|
class PrintJobTest < Test::Unit::TestCase
|
4
4
|
def setup
|
5
5
|
# TODO: Is it necessary to pass a fake token to #setup?
|
6
|
-
|
6
|
+
@client = new_client
|
7
7
|
stub_connection
|
8
8
|
end
|
9
9
|
|
10
10
|
should "find a job" do
|
11
11
|
fake_connection.stubs(:get).with('/jobs').returns(jobs_response)
|
12
|
-
assert
|
12
|
+
assert @client.print_jobs.find('job_id').is_a?(CloudPrint::PrintJob)
|
13
13
|
end
|
14
14
|
|
15
15
|
should 'perform a remote request when finding a job' do
|
16
16
|
fake_connection.expects(:get).with('/jobs').returns({})
|
17
17
|
|
18
|
-
|
18
|
+
@client.print_jobs.find('job_id')
|
19
19
|
end
|
20
20
|
|
21
21
|
should 'gets the job details' do
|
22
22
|
fake_connection.stubs(:get).with('/jobs').returns(jobs_response)
|
23
|
-
job =
|
23
|
+
job = @client.print_jobs.find('job_id')
|
24
24
|
|
25
25
|
assert_equal 'job_id', job.id
|
26
26
|
assert_equal 'status', job.status
|
27
27
|
assert_equal 'Error', job.error_code
|
28
|
+
assert_equal 'printer_id', job.printer_id
|
29
|
+
assert_equal 'Job Title', job.title
|
30
|
+
assert_equal 'image/jpeg', job.content_type
|
31
|
+
assert_equal 'https://www.google.com/cloudprint/download?id=job_id', job.file_url
|
32
|
+
assert_equal 'https://www.google.com/cloudprint/ticket?jobid=job_id', job.ticket_url
|
33
|
+
assert_equal Time.at(1349722237.676), job.create_time
|
34
|
+
assert_equal Time.at(1349722237.676), job.update_time
|
35
|
+
assert_equal 'A message.', job.message
|
36
|
+
assert_equal ["^own"], job.tags
|
28
37
|
end
|
29
38
|
|
30
39
|
should 'recognize a job as queued' do
|
31
|
-
job =
|
40
|
+
job = @client.print_jobs.new(:status => "QUEUED")
|
32
41
|
|
33
42
|
assert !job.done?
|
34
43
|
assert !job.in_progress?
|
@@ -39,7 +48,7 @@ class PrintJobTest < Test::Unit::TestCase
|
|
39
48
|
end
|
40
49
|
|
41
50
|
should 'recognize a job as in progress' do
|
42
|
-
job =
|
51
|
+
job = @client.print_jobs.new(:status => "IN_PROGRESS")
|
43
52
|
|
44
53
|
assert !job.done?
|
45
54
|
assert !job.queued?
|
@@ -50,7 +59,7 @@ class PrintJobTest < Test::Unit::TestCase
|
|
50
59
|
end
|
51
60
|
|
52
61
|
should 'recognize a job as done' do
|
53
|
-
job =
|
62
|
+
job = @client.print_jobs.new(:status => "DONE")
|
54
63
|
|
55
64
|
assert !job.in_progress?
|
56
65
|
assert !job.queued?
|
@@ -61,7 +70,7 @@ class PrintJobTest < Test::Unit::TestCase
|
|
61
70
|
end
|
62
71
|
|
63
72
|
should "recognize a job has an error" do
|
64
|
-
job =
|
73
|
+
job = @client.print_jobs.new(:status => "ERROR")
|
65
74
|
|
66
75
|
assert !job.done?
|
67
76
|
assert !job.in_progress?
|
@@ -72,7 +81,7 @@ class PrintJobTest < Test::Unit::TestCase
|
|
72
81
|
end
|
73
82
|
|
74
83
|
should "recognize a job as submitted" do
|
75
|
-
job =
|
84
|
+
job = @client.print_jobs.new(:status => "SUBMITTED")
|
76
85
|
|
77
86
|
assert !job.done?
|
78
87
|
assert !job.in_progress?
|
@@ -83,8 +92,8 @@ class PrintJobTest < Test::Unit::TestCase
|
|
83
92
|
end
|
84
93
|
|
85
94
|
should "refresh a job" do
|
86
|
-
job =
|
87
|
-
|
95
|
+
job = @client.print_jobs.new(:id => "job_id", :status => "IN_PROGRESS")
|
96
|
+
@client.print_jobs.stubs(:find_by_id).returns({"id" => "job_id", "status" => "DONE", "errorCode" => "42"})
|
88
97
|
|
89
98
|
assert_equal job, job.refresh!
|
90
99
|
|
@@ -92,13 +101,56 @@ class PrintJobTest < Test::Unit::TestCase
|
|
92
101
|
assert_equal "42", job.error_code
|
93
102
|
end
|
94
103
|
|
104
|
+
should "return all jobs" do
|
105
|
+
fake_connection.stubs(:get).with('/jobs').returns(jobs_response)
|
106
|
+
jobs = @client.print_jobs.all
|
107
|
+
|
108
|
+
assert jobs[0].id == 'other_job'
|
109
|
+
assert jobs[1].id == 'job_id'
|
110
|
+
end
|
111
|
+
|
112
|
+
context '#delete!' do
|
113
|
+
should "return true on success" do
|
114
|
+
fake_connection.stubs(:get).with('/deletejob', { :jobid => 'job_id' }).returns({ 'success' => true })
|
115
|
+
|
116
|
+
assert @client.print_jobs.new(:id => 'job_id').delete!
|
117
|
+
end
|
118
|
+
|
119
|
+
should "perform a remote request" do
|
120
|
+
fake_connection.expects(:get).with('/deletejob', { :jobid => 'job_id' }).returns({ 'success' => true })
|
121
|
+
|
122
|
+
@client.print_jobs.new(:id => 'job_id').delete!
|
123
|
+
end
|
124
|
+
|
125
|
+
should "raise a RequestError on failure" do
|
126
|
+
fake_connection.stubs(:get).with('/deletejob', { :jobid => 'job_id' }).returns({ 'success' => false, 'message' => 'This is an error', 'errorCode' => '123' })
|
127
|
+
|
128
|
+
assert_raise(CloudPrint::RequestError, 'This is an error') do
|
129
|
+
@client.print_jobs.new(:id => 'job_id').delete!
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
95
134
|
private
|
96
135
|
|
97
136
|
def jobs_response
|
98
137
|
{
|
99
138
|
"jobs" => [
|
100
|
-
{"id" => "other_job", "status" => "status", "errorCode" => "Error"},
|
101
|
-
{
|
139
|
+
{ "id" => "other_job", "status" => "status", "errorCode" => "Error" },
|
140
|
+
{
|
141
|
+
"id" => "job_id",
|
142
|
+
"status" => "status",
|
143
|
+
"errorCode" => "Error",
|
144
|
+
"printerid" => "printer_id",
|
145
|
+
"title" => "Job Title",
|
146
|
+
"contentType" => "image/jpeg",
|
147
|
+
"fileUrl" => "https://www.google.com/cloudprint/download?id=job_id",
|
148
|
+
"ticketUrl" => "https://www.google.com/cloudprint/ticket?jobid=job_id",
|
149
|
+
"createTime" => "1349722237676",
|
150
|
+
"updateTime" => "1349722237676",
|
151
|
+
"message" => "A message.",
|
152
|
+
"tags" => ["^own"]
|
153
|
+
}
|
102
154
|
]
|
103
155
|
}
|
104
156
|
end
|