heroku-client 0.0.1 → 0.0.2

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.
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: