capgun 0.0.1 → 0.0.3

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.
Files changed (57) hide show
  1. data/.gitignore +1 -0
  2. data/.rspec +3 -0
  3. data/Gemfile +1 -8
  4. data/Gemfile.lock +32 -0
  5. data/HISTORY.md +14 -3
  6. data/LICENSE.md +26 -0
  7. data/README.md +306 -4
  8. data/Rakefile +10 -2
  9. data/capgun.gemspec +27 -16
  10. data/examples/hubot/capgun.coffee +68 -0
  11. data/lib/capgun.rb +29 -1
  12. data/lib/capgun/account.rb +13 -0
  13. data/lib/capgun/base.rb +48 -0
  14. data/lib/capgun/client.rb +82 -0
  15. data/lib/capgun/config.rb +73 -0
  16. data/lib/capgun/connection.rb +36 -0
  17. data/lib/capgun/core_ext/hash.rb +19 -0
  18. data/lib/capgun/creatable.rb +21 -0
  19. data/lib/capgun/error.rb +17 -0
  20. data/lib/capgun/error/bad_gateway.rb +7 -0
  21. data/lib/capgun/error/bad_request.rb +7 -0
  22. data/lib/capgun/error/client_error.rb +7 -0
  23. data/lib/capgun/error/forbidden.rb +7 -0
  24. data/lib/capgun/error/internal_server_error.rb +7 -0
  25. data/lib/capgun/error/not_acceptable.rb +7 -0
  26. data/lib/capgun/error/not_found.rb +7 -0
  27. data/lib/capgun/error/server_error.rb +7 -0
  28. data/lib/capgun/error/service_unavailable.rb +7 -0
  29. data/lib/capgun/error/unauthorized.rb +7 -0
  30. data/lib/capgun/estimate.rb +11 -0
  31. data/lib/capgun/job.rb +13 -0
  32. data/lib/capgun/order.rb +13 -0
  33. data/lib/capgun/request.rb +33 -0
  34. data/lib/capgun/request/gateway.rb +20 -0
  35. data/lib/capgun/response/parse_json.rb +28 -0
  36. data/lib/capgun/response/raise_client_error.rb +48 -0
  37. data/lib/capgun/response/raise_server_error.rb +23 -0
  38. data/lib/capgun/version.rb +27 -7
  39. data/spec/capgun/account_spec.rb +45 -0
  40. data/spec/capgun/base_spec.rb +29 -0
  41. data/spec/capgun/client_spec.rb +181 -0
  42. data/spec/capgun/config_spec.rb +43 -0
  43. data/spec/capgun/estimate_spec.rb +7 -0
  44. data/spec/capgun/job_spec.rb +45 -0
  45. data/spec/capgun/order_spec.rb +45 -0
  46. data/spec/capgun/version_spec.rb +11 -0
  47. data/spec/capgun_spec.rb +17 -0
  48. data/spec/faraday/response_spec.rb +68 -0
  49. data/spec/fixtures/account.json +9 -0
  50. data/spec/fixtures/completed-order.json +46 -0
  51. data/spec/fixtures/estimate.json +34 -0
  52. data/spec/fixtures/job.json +9 -0
  53. data/spec/fixtures/notfound.json +1 -0
  54. data/spec/fixtures/order.json +43 -0
  55. data/spec/fixtures/unauthorized.json +1 -0
  56. data/spec/spec_helper.rb +27 -0
  57. metadata +218 -10
@@ -0,0 +1,7 @@
1
+ require 'capgun/error/client_error'
2
+
3
+ module Capgun
4
+ # Raised when Capgun returns the HTTP status code 403
5
+ class Error::Forbidden < Capgun::Error::ClientError
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'capgun/error/server_error'
2
+
3
+ module Capgun
4
+ # Raised when Capgun returns the HTTP status code 500
5
+ class Error::InternalServerError < Capgun::Error::ServerError
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'capgun/error/client_error'
2
+
3
+ module Capgun
4
+ # Raised when Capgun returns the HTTP status code 406
5
+ class Error::NotAcceptable < Capgun::Error::ClientError
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'capgun/error/client_error'
2
+
3
+ module Capgun
4
+ # Raised when Capgun returns the HTTP status code 404
5
+ class Error::NotFound < Capgun::Error::ClientError
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'capgun/error'
2
+
3
+ module Capgun
4
+ # Raised when Capgun returns a 5xx HTTP status code
5
+ class Error::ServerError < Capgun::Error
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'capgun/error/server_error'
2
+
3
+ module Capgun
4
+ # Raised when Capgun returns the HTTP status code 503
5
+ class Error::ServiceUnavailable < Capgun::Error::ServerError
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'capgun/error/client_error'
2
+
3
+ module Capgun
4
+ # Raised when Capgun returns the HTTP status code 401
5
+ class Error::Unauthorized < Capgun::Error::ClientError
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ module Capgun
2
+
3
+ # capgun capture estimate
4
+
5
+ class Estimate < Capgun::Base
6
+
7
+ lazy_attr_reader :url, :notify, :cost, :viewport, :packages, :images, :options
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,13 @@
1
+ module Capgun
2
+
3
+ # capgun job
4
+
5
+ class Job < Capgun::Base
6
+
7
+ include Capgun::Creatable
8
+
9
+ lazy_attr_reader :id, :state, :order_id
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,13 @@
1
+ module Capgun
2
+
3
+ # capgun capture order
4
+
5
+ class Order < Capgun::Base
6
+
7
+ include Capgun::Creatable
8
+
9
+ lazy_attr_reader :id, :url, :notify, :cost, :viewport, :packages, :images, :asset_urls, :options, :job
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,33 @@
1
+ module Capgun
2
+ # Defines HTTP request methods
3
+ module Request
4
+
5
+ # Perform an HTTP GET request
6
+ def get(path, params={}, options={})
7
+ request(:get, path, params, options)
8
+ end
9
+
10
+ # Perform an HTTP POST request
11
+ def post(path, params={}, options={})
12
+ request(:post, path, params, options)
13
+ end
14
+
15
+ private
16
+
17
+ # Perform an HTTP request
18
+ def request(method, path, params, options)
19
+ response = connection(options).run_request(method, nil, nil, nil) do |request|
20
+ request.options[:raw] = true if options[:raw]
21
+ case method.to_sym
22
+ when :get
23
+ request.url(path, params)
24
+ when :post
25
+ request.path = path
26
+ request.body = params.to_json unless params.empty?
27
+ end
28
+ end
29
+ options[:raw] ? response : response.body
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,20 @@
1
+ require 'faraday'
2
+
3
+ module Capgun
4
+ module Request
5
+ class Gateway < Faraday::Middleware
6
+
7
+ def call(env)
8
+ url = env[:url].dup
9
+ url.host = @gateway
10
+ env[:url] = url
11
+ @app.call(env)
12
+ end
13
+
14
+ def initialize(app, gateway)
15
+ @app, @gateway = app, gateway
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,28 @@
1
+ require 'faraday'
2
+ require 'multi_json'
3
+
4
+ module Capgun
5
+ module Response
6
+ class ParseJson < Faraday::Response::Middleware
7
+
8
+ def parse(body)
9
+ case body
10
+ when ''
11
+ nil
12
+ when 'true'
13
+ true
14
+ when 'false'
15
+ false
16
+ else
17
+ MultiJson.load(body)
18
+ end
19
+ end
20
+
21
+ def on_complete(env)
22
+ if respond_to? :parse
23
+ env[:body] = parse(env[:body]) unless env[:request][:raw] or [204,304].index env[:status]
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,48 @@
1
+ require 'faraday'
2
+ require 'capgun/error/bad_request'
3
+ require 'capgun/error/forbidden'
4
+ require 'capgun/error/not_acceptable'
5
+ require 'capgun/error/not_found'
6
+ require 'capgun/error/unauthorized'
7
+
8
+ module Capgun
9
+ module Response
10
+ class RaiseClientError < Faraday::Response::Middleware
11
+
12
+ def on_complete(env)
13
+ case env[:status].to_i
14
+ when 400
15
+ raise Capgun::Error::BadRequest.new(error_body(env[:body]), env[:response_headers])
16
+ when 401
17
+ raise Capgun::Error::Unauthorized.new(error_body(env[:body]), env[:response_headers])
18
+ when 403
19
+ raise Capgun::Error::Forbidden.new(error_body(env[:body]), env[:response_headers])
20
+ when 404
21
+ raise Capgun::Error::NotFound.new(error_body(env[:body]), env[:response_headers])
22
+ when 406
23
+ raise Capgun::Error::NotAcceptable.new(error_body(env[:body]), env[:response_headers])
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def error_body(body)
30
+ if body.nil?
31
+ ''
32
+ elsif body['message']
33
+ body['message']
34
+ elsif body['error']
35
+ body['error']
36
+ elsif body['errors']
37
+ first = Array(body['errors']).first
38
+ if first.kind_of?(Hash)
39
+ first['message'].chomp
40
+ else
41
+ first.chomp
42
+ end
43
+ end
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,23 @@
1
+ require 'faraday'
2
+ require 'capgun/error/bad_gateway'
3
+ require 'capgun/error/internal_server_error'
4
+ require 'capgun/error/service_unavailable'
5
+
6
+ module Capgun
7
+ module Response
8
+ class RaiseServerError < Faraday::Response::Middleware
9
+
10
+ def on_complete(env)
11
+ case env[:status].to_i
12
+ when 500
13
+ raise Capgun::Error::InternalServerError.new("Something is technically wrong.", env[:response_headers])
14
+ when 502
15
+ raise Capgun::Error::BadGateway.new("Capgun is down!", env[:response_headers])
16
+ when 503
17
+ raise Capgun::Error::ServiceUnavailable.new("(__-){ Capgun is over capacity.", env[:response_headers])
18
+ end
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -1,10 +1,30 @@
1
- module Capgun #:nodoc:
2
- module VERSION #:nodoc:
3
- MAJOR = 0
4
- MINOR = 0
5
- TINY = 1
1
+ module Capgun
2
+ class Version
3
+
4
+ # @return [Integer]
5
+ def self.major
6
+ 0
7
+ end
8
+
9
+ # @return [Integer]
10
+ def self.minor
11
+ 0
12
+ end
13
+
14
+ # @return [Integer]
15
+ def self.patch
16
+ 3
17
+ end
18
+
19
+ # @return [String, NilClass]
20
+ def self.pre
21
+ nil
22
+ end
23
+
24
+ # @return [String]
25
+ def self.to_s
26
+ [major, minor, patch, pre].compact.join('.')
27
+ end
6
28
 
7
- STRING = [MAJOR, MINOR, TINY].join('.')
8
29
  end
9
30
  end
10
-
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe Capgun::Account do
4
+
5
+ describe "#==" do
6
+ it "should return true when ids and classes are equal" do
7
+ user = Capgun::Account.new('id' => 1)
8
+ other = Capgun::Account.new('id' => 1)
9
+ (user == other).should be_true
10
+ end
11
+ it "should return false when classes are not equal" do
12
+ user = Capgun::Account.new('id' => 1)
13
+ other = Capgun::Order.new('id' => 1)
14
+ (user == other).should be_false
15
+ end
16
+ it "should return false when ids are not equal" do
17
+ user = Capgun::Account.new('id' => 1)
18
+ other = Capgun::Job.new('id' => 2)
19
+ (user == other).should be_false
20
+ end
21
+ end
22
+
23
+ describe "#created_at" do
24
+ it "should return a Time when created_at is set" do
25
+ user = Capgun::Account.new('created_at' => "Mon Jul 16 12:59:01 +0000 2007")
26
+ user.created_at.should be_a Time
27
+ end
28
+ it "should return nil when created_at is not set" do
29
+ user = Capgun::Account.new
30
+ user.created_at.should be_nil
31
+ end
32
+ end
33
+
34
+ describe "#updated_at" do
35
+ it "should return a Time when updated_at is set" do
36
+ user = Capgun::Account.new('updated_at' => "Mon Jul 16 12:59:01 +0000 2007")
37
+ user.updated_at.should be_a Time
38
+ end
39
+ it "should return nil when updated_at is not set" do
40
+ user = Capgun::Account.new
41
+ user.updated_at.should be_nil
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Capgun::Base do
4
+
5
+ before do
6
+ @base = Capgun::Base.new('id' => 1)
7
+ end
8
+
9
+ describe "#[]" do
10
+ it "should be able to call methods using [] with symbol" do
11
+ @base[:object_id].should be_an Integer
12
+ end
13
+ it "should be able to call methods using [] with string" do
14
+ @base['object_id'].should be_an Integer
15
+ end
16
+ it "should return nil for missing method" do
17
+ @base[:foo].should be_nil
18
+ @base['foo'].should be_nil
19
+ end
20
+ end
21
+
22
+ describe "#to_hash" do
23
+ it "should return a hash" do
24
+ @base.to_hash.should be_a Hash
25
+ @base.to_hash['id'].should == 1
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,181 @@
1
+ require 'spec_helper'
2
+
3
+ describe Capgun::Client do
4
+
5
+ before do
6
+ @keys = Capgun::Config::VALID_OPTIONS_KEYS
7
+ end
8
+
9
+ context "invalid client" do
10
+
11
+ specify "not allowed to get estimates without authorization" do
12
+ stub_request(:post, "https://api.capgun.io/v1/orders/estimate.json").
13
+ with(:body => "{\"url\":\"http://example.com/test\"}",
14
+ :headers => {'Accept'=>'application/json', 'Authorization'=>'', 'User-Agent'=>'Capgun.io Ruby Gem 0.0.3'}).
15
+ to_return(:status => 401, :body => fixture("unauthorized.json"), :headers => {})
16
+
17
+ lambda { Capgun.estimate("http://example.com/test") }.should raise_error(Capgun::Error::Unauthorized, "Unauthorized")
18
+ end
19
+
20
+ specify "no urls are submitted for capture" do
21
+ stub_request(:post, "https://api.capgun.io/v1/orders.json").
22
+ with(:body => "{\"url\":\"http://example.com/test\"}",
23
+ :headers => {'Accept'=>'application/json', 'Authorization'=>'', 'User-Agent'=>'Capgun.io Ruby Gem 0.0.3'}).
24
+ to_return(:status => 401, :body => fixture("unauthorized.json"), :headers => {})
25
+
26
+ lambda { Capgun.capture("http://example.com/test") }.should raise_error(Capgun::Error::Unauthorized, "Unauthorized")
27
+ end
28
+
29
+ specify "not allowed to view on order without authorization" do
30
+ stub_request(:get, "https://api.capgun.io/v1/orders/4fd20a1288f560177600000a.json").
31
+ with(:headers => {'Accept'=>'application/json', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>'', 'User-Agent'=>'Capgun.io Ruby Gem 0.0.3'}).
32
+ to_return(:status => 401, :body => fixture("unauthorized.json"), :headers => {})
33
+
34
+ lambda { Capgun.order("4fd20a1288f560177600000a") }.should raise_error(Capgun::Error::Unauthorized, "Unauthorized")
35
+ end
36
+
37
+ specify "not allowed to view job status without authorization" do
38
+ stub_request(:get, "https://api.capgun.io/v1/jobs/4fd20a1288f5601776000012.json").
39
+ with(:headers => {'Accept'=>'application/json', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>'', 'User-Agent'=>'Capgun.io Ruby Gem 0.0.3'}).
40
+ to_return(:status => 401, :body => fixture('unauthorized.json'), :headers => {})
41
+
42
+ lambda { Capgun.status("4fd20a1288f5601776000012") }.should raise_error(Capgun::Error::Unauthorized, "Unauthorized")
43
+ end
44
+
45
+ specify "not allowed to view account" do
46
+ stub_request(:get, "https://api.capgun.io/v1/account.json").
47
+ with(:headers => {'Accept'=>'application/json', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>'', 'User-Agent'=>'Capgun.io Ruby Gem 0.0.3'}).
48
+ to_return(:status => 401, :body => fixture('unauthorized.json'), :headers => {})
49
+
50
+ lambda { Capgun.account }.should raise_error(Capgun::Error::Unauthorized, "Unauthorized")
51
+ end
52
+
53
+ end
54
+
55
+ context "client with capture credits" do
56
+
57
+ before do
58
+ Capgun.configure do |config|
59
+ config.auth_token = 'test'
60
+ end
61
+ end
62
+
63
+ after do
64
+ Capgun.reset
65
+ end
66
+
67
+ specify "get an estimate to capture a url" do
68
+ stub_request(:post, "https://api.capgun.io/v1/orders/estimate.json").
69
+ with(:body => "{\"url\":\"http://example.com/test\"}",
70
+ :headers => {'Accept'=>'application/json', 'Authorization'=>'test', 'User-Agent'=>'Capgun.io Ruby Gem 0.0.3'}).
71
+ to_return(:status => 200, :body => fixture("estimate.json"), :headers => {})
72
+
73
+ estimate = Capgun.estimate("http://example.com/test")
74
+ estimate.cost.should == 1
75
+ end
76
+
77
+ specify "urls are submitted for capture" do
78
+ stub_request(:post, "https://api.capgun.io/v1/orders.json").
79
+ with(:body => "{\"url\":\"http://example.com/test\"}",
80
+ :headers => {'Accept'=>'application/json', 'Authorization'=>'test', 'User-Agent'=>'Capgun.io Ruby Gem 0.0.3'}).
81
+ to_return(:status => 200, :body => fixture("order.json"), :headers => {})
82
+
83
+ order = Capgun.capture("http://example.com/test")
84
+ order.id.should == '4fd20a1288f560177600000a'
85
+ order.cost.should == 1
86
+ end
87
+
88
+ specify "showing a capture order" do
89
+ stub_request(:get, "https://api.capgun.io/v1/orders/4fd20a1288f560177600000a.json").
90
+ with(:headers => {'Accept'=>'application/json', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>'test', 'User-Agent'=>'Capgun.io Ruby Gem 0.0.3'}).
91
+ to_return(:status => 200, :body => fixture("order.json"), :headers => {})
92
+
93
+ order = Capgun.order("4fd20a1288f560177600000a")
94
+ order.id.should == '4fd20a1288f560177600000a'
95
+ order.cost.should == 1
96
+ end
97
+
98
+ specify "capture jobs have a status" do
99
+ stub_request(:get, "https://api.capgun.io/v1/jobs/4fd20a1288f5601776000012.json").
100
+ with(:headers => {'Accept'=>'application/json', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>'test', 'User-Agent'=>'Capgun.io Ruby Gem 0.0.3'}).
101
+ to_return(:status => 200, :body => fixture('job.json'), :headers => {})
102
+
103
+
104
+ job = Capgun.status("4fd20a1288f5601776000012")
105
+ job.id.should == '4fd20a1288f5601776000012'
106
+ job.state.should == 'initialized'
107
+ end
108
+
109
+ specify "account can be retrieved" do
110
+ stub_request(:get, "https://api.capgun.io/v1/account.json").
111
+ with(:headers => {'Accept'=>'application/json', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>'test', 'User-Agent'=>'Capgun.io Ruby Gem 0.0.3'}).
112
+ to_return(:status => 200, :body => fixture('account.json'), :headers => {})
113
+
114
+ account = Capgun.account
115
+ account.id.should == '4fd193db88f5600472000001'
116
+ account.name.should == 'Acme Co.'
117
+ account.balance.should == 200
118
+ end
119
+
120
+ end
121
+
122
+ context "with module configuration" do
123
+
124
+ before do
125
+ Capgun.configure do |config|
126
+ @keys.each do |key|
127
+ config.send("#{key}=", key)
128
+ end
129
+ end
130
+ end
131
+
132
+ after do
133
+ Capgun.reset
134
+ end
135
+
136
+ specify "should inherit module configuration" do
137
+ api = Capgun::Client.new
138
+ @keys.each do |key|
139
+ api.send(key).should == key
140
+ end
141
+ end
142
+
143
+ context "with class configuration" do
144
+
145
+ before do
146
+ @configuration = {
147
+ :adapter => :net_http,
148
+ :connection_options => nil,
149
+ :endpoint => 'http://example.com/',
150
+ :gateway => nil,
151
+ :auth_token => 'AT',
152
+ :user_agent => 'Custom User Agent',
153
+ :proxy => nil,
154
+ }
155
+ end
156
+
157
+ context "during initialization" do
158
+ it "should override module configuration" do
159
+ api = Capgun::Client.new(@configuration)
160
+ @keys.each do |key|
161
+ api.send(key).should == @configuration[key]
162
+ end
163
+ end
164
+ end
165
+
166
+ context "after initilization" do
167
+ it "should override module configuration after initialization" do
168
+ api = Capgun::Client.new
169
+ @configuration.each do |key, value|
170
+ api.send("#{key}=", value)
171
+ end
172
+ @keys.each do |key|
173
+ api.send(key).should == @configuration[key]
174
+ end
175
+ end
176
+ end
177
+
178
+ end
179
+ end
180
+
181
+ end