capgun 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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