heroku-client 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -16,3 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  *.swp
19
+ *.swo
data/lib/heroku-client.rb CHANGED
@@ -2,6 +2,7 @@ require "httparty"
2
2
  require "json"
3
3
 
4
4
  require "heroku-client/version"
5
+ require "heroku-client/json_util"
5
6
  require "heroku-client/heroku_obj"
6
7
  require "heroku-client/http"
7
8
  require "heroku-client/api"
@@ -13,6 +13,37 @@ module Heroku
13
13
  raise "Invalid number of parameters"
14
14
  end
15
15
 
16
+ def create_app(params = {})
17
+ post_params = {}
18
+
19
+ [:name, :stack].each do |k|
20
+ post_params["app[#{k}]"] = params[k] if params.has_key? k
21
+ end
22
+
23
+ post "apps", post_params
24
+ end
25
+
26
+ def rename_app(old_app_name, new_app_name)
27
+ put_params = {}
28
+
29
+ put_params["name"] = old_app_name
30
+ put_params["app[name]"] = new_app_name
31
+
32
+ put "apps/#{old_app_name}", put_params
33
+ end
34
+
35
+ def transfer_app(app_name, new_owner)
36
+ put_params = {}
37
+
38
+ put_params["app[transfer_owner]"] = new_owner
39
+
40
+ put "apps/#{app_name}", put_params
41
+ end
42
+
43
+ def delete_app(app_name)
44
+ delete "apps/#{app_name}"
45
+ end
46
+
16
47
  def collaborators(app_name)
17
48
  return get("apps/#{app_name}/collaborators")
18
49
  end
@@ -2,27 +2,62 @@ module Heroku
2
2
  module Client
3
3
  module Http
4
4
  def get(uri)
5
+ request :get, uri
6
+ end
7
+
8
+ def post(uri, body)
9
+ request :post, uri, body
10
+ end
11
+
12
+ def put(uri, body)
13
+ request :put, uri, body
14
+ end
15
+
16
+ def delete(uri)
17
+ request :delete, uri
18
+ end
19
+
20
+ def request(method, uri, body = {})
5
21
  headers = { "Accept" => "application/json"}
6
- resp = HTTParty.get "https://api.heroku.com/#{uri}", { basic_auth: { password: apikey }, headers: headers}
22
+ basic_auth = { password: apikey }
7
23
 
8
- raise UnauthorizedError if resp.code == 401
9
- raise PaymentRequiredError if resp.code == 402
10
- raise ForbiddenError if resp.code == 403
11
- raise NotFoundError if resp.code == 404
12
- raise PreConditionFailedError if resp.code == 412
13
- raise UnprocessableEntityError if resp.code == 422
14
- raise LockedError if resp.code == 423
24
+ options = { basic_auth: basic_auth, headers: headers }
15
25
 
16
- raise UnknownError unless resp.success?
26
+ options[:body] = body unless body.empty?
17
27
 
18
- parsed = JSON.parse(resp.body)
28
+ url = "https://api.heroku.com/#{uri}"
29
+
30
+ resp = HTTParty.get url, options if method == :get
31
+ resp = HTTParty.post url, options if method == :post
32
+ resp = HTTParty.put url, options if method == :put
33
+ resp = HTTParty.delete url, options if method == :delete
34
+
35
+ unless resp.success?
36
+ error_message = json_util.parse_error(resp.body)
37
+
38
+ raise UnauthorizedError, error_message if resp.code == 401
39
+ raise PaymentRequiredError, error_message if resp.code == 402
40
+ raise ForbiddenError, error_message if resp.code == 403
41
+ raise NotFoundError, error_message if resp.code == 404
42
+ raise PreConditionFailedError, error_message if resp.code == 412
43
+ raise UnprocessableEntityError, error_message if resp.code == 422
44
+ raise LockedError, error_message if resp.code == 423
19
45
 
46
+ raise UnknownError
47
+ end
48
+
49
+ parsed = JSON.parse(resp.body)
20
50
  parsed = parsed.map { |o| HerokuObj.new(o) } if parsed.is_a? Array
21
51
 
22
52
  parsed = HerokuObj.new parsed if parsed.is_a? Hash
23
53
 
24
54
  parsed
25
55
  end
56
+
57
+ private
58
+ def json_util
59
+ @json_util ||= JSONUtil.new
60
+ end
26
61
  end
27
62
 
28
63
  class UnauthorizedError < Exception
@@ -0,0 +1,26 @@
1
+ module Heroku
2
+ module Client
3
+ class JSONUtil
4
+
5
+ def parse_error(body)
6
+ parse_json_error(body) || parse_plain_text_error(body)
7
+ end
8
+
9
+ def parse_json_error(body)
10
+ json = JSON.parse body rescue false
11
+
12
+ case json
13
+ when Array
14
+ json.first.join ' ' # message like [["name", "is already taken"]]
15
+ when Hash
16
+ json['error'] # message like {"error": "The error message"}
17
+ end
18
+ end
19
+
20
+ def parse_plain_text_error(body)
21
+ body
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -1,5 +1,5 @@
1
1
  module Heroku
2
2
  module Client
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
@@ -14,6 +14,14 @@ describe Heroku::Client::Api do
14
14
  FakeWeb.register_uri :get, Responses::Api.processes_url(api.apikey, app_name), body: Responses::Api.processes
15
15
  FakeWeb.register_uri :get, Responses::Api.releases_url(api.apikey, app_name), body: Responses::Api.releases
16
16
  FakeWeb.register_uri :get, Responses::Api.stacks_url(api.apikey, app_name), body: Responses::Api.stacks
17
+
18
+ FakeWeb.register_uri :post, Responses::Api.apps_url(api.apikey), body: Responses::Api.create_app
19
+ #FakeWeb.register_uri :post, Responses::Api.apps_url(api.apikey), request_body: "app[name]=test_app&app[stack]=bamboo", body: Responses::Api.create_app("test_app", "bamboo")
20
+
21
+ FakeWeb.register_uri :put, Responses::Api.rename_app_url(api.apikey), body: Responses::Api.rename_app
22
+ FakeWeb.register_uri :put, Responses::Api.transfer_app_url(api.apikey), body: Responses::Api.transfer_app
23
+
24
+ FakeWeb.register_uri :delete, Responses::Api.apps_by_name_url(api.apikey), body: "{}"
17
25
  end
18
26
 
19
27
  let(:api) { Heroku::Client::Api.new "apikey" }
@@ -36,6 +44,42 @@ describe Heroku::Client::Api do
36
44
  end
37
45
  end
38
46
 
47
+ describe "#create_app" do
48
+ it "returns created app" do
49
+ api.create_app.stack.should eq("cedar")
50
+ end
51
+
52
+ =begin
53
+ context "when parameters are passed" do
54
+ let(:created_app) { api.create_app name: "test_app", stack: "bamboo" }
55
+
56
+ it "returns created app with given name" do
57
+ created_app.name.should eq("test_app")
58
+ end
59
+
60
+ it "returns create app with given stack"
61
+ end
62
+ =end
63
+ end
64
+
65
+ describe "#rename_app" do
66
+ it "returns the new name for app" do
67
+ api.rename_app("example_old", "example_new").name.should eq("example_new")
68
+ end
69
+ end
70
+
71
+ describe "#transfer_app" do
72
+ it "is success" do
73
+ api.transfer_app "example", "new_owner@email.com"
74
+ end
75
+ end
76
+
77
+ describe "#delete_app" do
78
+ it "is success" do
79
+ api.delete_app "example"
80
+ end
81
+ end
82
+
39
83
  describe "#collaborators" do
40
84
  let(:collaborators) { api.collaborators(app_name) }
41
85
 
@@ -14,35 +14,37 @@ describe Heroku::Client::Http do
14
14
  Http.new
15
15
  end
16
16
 
17
- describe ".get" do
17
+ describe "#request" do
18
18
  context "success" do
19
19
  before do
20
20
  FakeWeb.register_uri :get, Responses::Api.apps_url(http.apikey), body: Responses::Api.apps
21
21
  FakeWeb.register_uri :get, Responses::Api.apps_by_name_url(http.apikey), body: Responses::Api.apps_by_name
22
22
  end
23
23
 
24
+ let(:result) { http.request(:get, "apps") }
25
+
24
26
  it "parses the response body" do
25
- http.get("apps").should be_a(Array)
27
+ result.should be_a(Array)
26
28
  end
27
29
 
28
30
  it "parses the json hash to HerokuObj" do
29
- http.get("apps").first.should be_a(Heroku::Client::HerokuObj)
31
+ result.first.should be_a(Heroku::Client::HerokuObj)
30
32
  end
31
33
 
32
34
  it "parses the json hash to HerokuObj" do
33
- http.get("apps/example").should be_a(Heroku::Client::HerokuObj)
35
+ http.request(:get, "apps/example").should be_a(Heroku::Client::HerokuObj)
34
36
  end
35
37
  end
36
38
 
37
39
  shared_examples "http request error" do |http_code, http_msg, error_class|
38
40
  before do
39
- FakeWeb.register_uri :get, "https://:apikey@api.heroku.com/apps", status: [http_code, http_msg]
41
+ FakeWeb.register_uri :get, "https://:apikey@api.heroku.com/apps", status: [http_code, http_msg], body: '{ "error": "The error message" }'
40
42
  end
41
43
 
42
44
  it "raises #{error_class}" do
43
45
  expect {
44
- http.get("apps")
45
- }.to raise_error(error_class)
46
+ http.request(:get, "apps")
47
+ }.to raise_error(error_class, 'The error message')
46
48
  end
47
49
  end
48
50
 
@@ -75,7 +77,15 @@ describe Heroku::Client::Http do
75
77
  end
76
78
 
77
79
  context "unknown error" do
78
- it_behaves_like "http request error", "500", "Unknown Error", Heroku::Client::UnknownError
80
+ before do
81
+ FakeWeb.register_uri :get, "https://:apikey@api.heroku.com/apps", status: ["500", "Internal Server Error"], body: '{ "error": "The error message" }'
82
+ end
83
+
84
+ it "raises UnkownError" do
85
+ expect {
86
+ http.request :get, "apps"
87
+ }.to raise_error(Heroku::Client::UnknownError)
88
+ end
79
89
  end
80
90
  end
81
91
  end
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ describe Heroku::Client::JSONUtil do
4
+
5
+ describe "#parse_error" do
6
+ let(:json) { Heroku::Client::JSONUtil.new }
7
+
8
+ shared_examples "error parser" do |body, expected|
9
+ it "should parse error" do
10
+ json.parse_error(body).should eq(expected)
11
+ end
12
+ end
13
+
14
+ context "when error is json" do
15
+ context "and error is object" do
16
+ it_behaves_like "error parser", '{ "error": "The error message" }', "The error message"
17
+ end
18
+
19
+ context "and error is array" do
20
+ it_behaves_like "error parser", '[["name","is already taken"]]', 'name is already taken'
21
+ end
22
+ end
23
+
24
+ context "when error is plain text" do
25
+ it_behaves_like "error parser", 'Some plain text error message', 'Some plain text error message'
26
+ end
27
+ end
28
+
29
+ end
@@ -24,6 +24,48 @@ module Responses
24
24
  EJSON
25
25
  end
26
26
 
27
+ def self.create_app(app_name = "example", stack = "cedar")
28
+ <<-EJSON
29
+ {
30
+ "id": 1000000,
31
+ "name": "#{app_name}",
32
+ "create_status": "complete",
33
+ "created_at": "2011/01/01 00:00:00 -0700",
34
+ "stack": "#{stack}",
35
+ "requested_stack": null,
36
+ "repo_migrate_status": "complete",
37
+ "slug_size": 1000000,
38
+ "repo_size": 1000000,
39
+ "dynos": 1,
40
+ "workers": 0
41
+ }
42
+ EJSON
43
+ end
44
+
45
+ def self.rename_app_url(apikey)
46
+ base_url apikey, "apps/example_old"
47
+ end
48
+
49
+ def self.rename_app
50
+ <<-EJSON
51
+ {
52
+ "name": "example_new"
53
+ }
54
+ EJSON
55
+ end
56
+
57
+ def self.transfer_app_url(apikey)
58
+ base_url apikey, "apps/example"
59
+ end
60
+
61
+ def self.transfer_app
62
+ <<-EJSON
63
+ {
64
+ "name": "name"
65
+ }
66
+ EJSON
67
+ end
68
+
27
69
  def self.apps_by_name_url(apikey)
28
70
  base_url(apikey, "apps/example")
29
71
  end
data/spec/spec_helper.rb CHANGED
@@ -13,3 +13,8 @@ shared_examples "attribute" do |attr, expected|
13
13
  end
14
14
  end
15
15
 
16
+ RSpec.configure do |config|
17
+ config.after :each do
18
+ FakeWeb.clean_registry
19
+ end
20
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heroku-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-27 00:00:00.000000000 Z
12
+ date: 2012-07-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httparty
@@ -110,10 +110,12 @@ files:
110
110
  - lib/heroku-client/api.rb
111
111
  - lib/heroku-client/heroku_obj.rb
112
112
  - lib/heroku-client/http.rb
113
+ - lib/heroku-client/json_util.rb
113
114
  - lib/heroku-client/version.rb
114
115
  - spec/heroku-client/api_spec.rb
115
116
  - spec/heroku-client/heroku_obj_spec.rb
116
117
  - spec/heroku-client/http_spec.rb
118
+ - spec/heroku-client/json_util_spec.rb
117
119
  - spec/heroku-client_spec.rb
118
120
  - spec/responses/api.rb
119
121
  - spec/spec_helper.rb
@@ -145,6 +147,8 @@ test_files:
145
147
  - spec/heroku-client/api_spec.rb
146
148
  - spec/heroku-client/heroku_obj_spec.rb
147
149
  - spec/heroku-client/http_spec.rb
150
+ - spec/heroku-client/json_util_spec.rb
148
151
  - spec/heroku-client_spec.rb
149
152
  - spec/responses/api.rb
150
153
  - spec/spec_helper.rb
154
+ has_rdoc: